![](/img/trans.png)
[英]How to have conditional defaultValues from useEffect in react-select within react-hook-form?
[英]How to change React-Hook-Form defaultValue with useEffect()?
我正在创建一个页面供用户使用 React-Hook-Form 更新个人数据。 加载 paged 后,我使用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
state。
{
name: "John",
phone: "02-98541566"
...
}
我还尝试在setUserData
useEffect()
中使用模拟数据设置用户数据,但它也不起作用。 我上面的代码有什么问题吗?
您可以使用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]);
您可以从表单中删除默认值。
编辑:如果这不起作用,请参阅下面的替代答案。
@tam 答案是使它与 6.8.3 版一起工作所需的一半。
你需要提供默认值还要使用Effect来重置。 如果您有一个与另一个实体一起重新加载的表单,则需要这种特殊的区别。 我在CodeSanbox中有一个完整的例子。
简而言之:您需要在userForm
中定义您的 defaultValues 。
const { register, reset, handleSubmit } = useForm({
defaultValues: useMemo(() => {
return props.user;
}, [props])
});
然后你需要倾听潜在的变化。
useEffect(() => {
reset(props.user);
}, [props.user]);
代码沙箱中的示例允许在两个用户之间进行交换并让表单更改其值。
setValue 对我不起作用。 或者,您可以使用重置方法。 我在下面分享一个工作代码块。 我希望这个对你有用。
...
/* 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: registeredAddresses[0].name,
tel: registeredAddresses[0].contactNumber,
});
}
}, [registeredAddresses]);
...
@tommcandrew 的setValue参数格式对我不起作用。
这种格式做了:
useEffect(() => {
const object = localStorage.getItem('object');
setValue("name", object.name);
}, [])
虽然这篇文章已有 2 个月的历史,但我今天偶然发现了这个问题,并寻找了几种方法来做到这一点。 我想出的最有效的方法是使用 useMemo 来设置你的 defaultValues,像这样:
const { control, errors, handleSubmit } = useForm({
reValidateMode: 'onChange',
defaultValues: useMemo(() => yourDefaultValues, [yourDefaultValues]),
});
这允许您在表单中正确设置值,如果您碰巧有字段 arrays (这是我的情况),则无需多次实现的斗争。
这也适用于使用官方文档中的 高级智能表单组件示例。 如果您有任何问题,请告诉我!
这适用于嵌套对象(我使用的是 6.15.1 版)
useEffect(() => {
for (const [key, value] of Object.entries(data)) {
setValue(key, value, {
shouldValidate: true,
shouldDirty: true,
});
}
},[data])
找到了另一种简单的方法,我使用了从 useForm reset
API
const { handleSubmit, register, reset } = useForm({ resolver });
调用 API 并取回响应数据后,使用新的 apiData 调用reset
,确保 apiData 键与输入键(名称属性)相同:
useEffect(() => {
reset(apiData);
}, [apiData]);
表单的默认值被缓存,因此一旦您从 API 获取数据,我们将使用新数据重置表单 state。
使用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
// }
});
现在 defaultValue 字段类型如下所示:
type AsyncDefaultValues<TFieldValues> = (payload?: unknown) => Promise<TFieldValues>;
isLoading用于加载 state 的异步默认值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.