如何使用useEffect()更改React-Hook-Form defaultValue?



我正在创建一个页面,供用户使用React-Hook-Form更新个人数据。 加载分页后,我使用useEffect获取用户的当前个人数据并将其设置为表单的默认值。

我将获取的值放入<Controller />defaultValue中。 但是,它只是没有显示在文本框中。 这是我的代码:

import React, {useState, useEffect, useCallback} from 'react';
import { useForm, Controller } from 'react-hook-form'
import { URL } from '../constants';
const UpdateUserData = props => {
const [userData, setUserData] = useState(null);
const { handleSubmit, control} = useForm({mode: 'onBlur'});
const fetchUserData = useCallback(async account => {
const userData = await fetch(`${URL}/user/${account}`)
.then(res=> res.json());
console.log(userData);
setUserData(userData);
}, []);
useEffect(() => {
const account = localStorage.getItem('account');
fetchUserData(account);
}, [fetchUserData])
const onSubmit = async (data) => {
// TODO
}
return (
<div>
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label>User Name:</label>
<Controller
as={<input type='text' />}
control={control}
defaultValue={userData ? userData.name : ''}
name='name'
/>
</div>

<div>
<label>Phone:</label>
<Controller
as={<input type='text' />}
control={control}
defaultValue={userData ? userData.phone : ''}
name='phone'
/>
</div>
<button>Submit</button>
</form>
</div>
);
}
export default UpdateUserData;

调用的 API 运行良好,该值实际上设置为userData状态。

{
name: "John",
phone: "02-98541566"
...
}

我还尝试setUserDatauseEffect()中的模拟数据,但它也不起作用。 我的上述代码有问题吗?

@tam答案已经完成了使其与版本6.8.3一起使用所需的一半。

您需要提供默认值,还需要使用 Effect 进行重置。如果您有一个使用另一个实体重新加载的表单,则需要这种特殊的区别。我在CodeSanbox中有一个完整的示例。

简而言之:您需要在userForm中定义默认值。

const { register, reset, handleSubmit } = useForm({
defaultValues: useMemo(() => {
return props.user;
}, [props])
});

然后你需要倾听潜在的变化。

useEffect(() => {
reset(props.user);
}, [props.user]);

代码沙箱中的示例允许在两个用户之间交换,并让表单更改其值。

您可以使用setValue(https://react-hook-form.com/api/useform/setvalue(。

从useForm导入它:

const { handleSubmit, control, setValue} = useForm({ mode: 'onBlur' });

然后在收到用户数据后使用用户数据调用它:

useEffect(() => {
if (userData) {
setValue([
{ name: userData.name }, 
{ phone: userData.phone }
]);
}
}, [userData]);

您可以从表单中删除默认值。

编辑:如果这不起作用,请参阅下面的替代答案。

setValue

对我不起作用。或者,您可以使用reset方法:

重置整个窗体状态或部分窗体状态。

这是工作代码:

/* registered address */
const [registeredAddresses, setRegisteredAddresses] = useState([]);
const { register, errors, handleSubmit, reset } = useForm <FormProps> ({
validationSchema: LoginSchema,
});
/**
* get addresses data
*/
const getRegisteredAddresses = async () => {
try {
const addresses = await AddressService.getAllAddress();
setRegisteredAddresses(addresses);
setDataFetching(false);
} catch (error) {
setDataFetching(false);
}
};
useEffect(() => {
getRegisteredAddresses();
}, []);
useEffect(() => {
if (registeredAddresses) {
reset({
addressName: registeredAddresses[0].name,
tel: registeredAddresses[0].contactNumber
});
}
}, [registeredAddresses]); 

找到了另一种简单的方法,我使用了useFormresetAPI

const { handleSubmit, register, reset } = useForm({ resolver });

调用 API 并获取响应数据后,使用新的 apiData 调用reset,确保 apiData 键与输入键(name 属性(相同:

useEffect(() => {
reset(apiData);
}, [apiData]);

表单的默认值被缓存,因此一旦您从 API 获取数据,我们就使用新数据重置表单状态。

@tommcandrew的setValue参数格式对我不起作用。

这种格式确实:

useEffect(() => {
const object = localStorage.getItem('object');
setValue("name", object.name);
}, [])

虽然这篇文章已经 2 个月了,但我今天偶然发现了这个问题,并搜索了几种方法来做到这一点。我想出的最有效的方法是使用 useMemo 来设置默认值,如下所示:

const { control, errors, handleSubmit } = useForm({
reValidateMode: 'onChange',
defaultValues: useMemo(() => yourDefaultValues, [yourDefaultValues]),
});

这允许您在表单中正确设置值,如果您碰巧有字段数组(这是我的情况(,则无需多个实现的挣扎。

这在使用官方文档中的高级智能表单组件示例时也有效。如果您有任何问题,请告诉我!

这适用于嵌套对象(我使用的是6.15.1版本(

useEffect(() => {
for (const [key, value] of Object.entries(data)) {
setValue(key, value, {
shouldValidate: true,
shouldDirty: true
})
}
}, [data])

使用reset是一个简单的解决方案。

const { reset } = useForm();

onClick={()=> reset({ firstname: 'Joe' }, { lastname: 'Doe' }) }

从 react-hook-form 7.41 开始,您可以将 defaultValues 与异步函数一起使用,如下所示:

const {
formState: { isLoading },
} = useForm({
defaultValues: fetch('API'),
// resetOptions: {
//   keepDirtyValues: true
// }
});

现在,默认值字段类型如下所示:

type AsyncDefaultValues<TFieldValues> = (payload?: unknown) => Promise<TFieldValues>;

是异步默认值加载状态的加载。

文档提到了一种在状态更改时设置默认值的方法 此处 https://react-hook-form.com/api/useform/#values

function App({ values }) {
useForm({
values  // will get updated when values props updates       
})
}

我在使用上述方法重置表单时遇到问题,因为它会导致无限循环。

react hook form Maximum update depth exceeded

因此,我尝试使用 useImpact 重置这些值,但仍然不起作用。

现在,我意识到如果我必须重置整个表单,那么我已经做了如下所示的事情并且它起作用了。

useEffect(()=>{
reset({...dataFromApi});
}, [quote])

相关内容

  • 没有找到相关文章

最新更新