如何使用 useEffect() 更改 React-Hook-Form defaultValue?
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
状态。
{
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]);
您可以从表单中删除默认值。
编辑:如果这不起作用,请参阅下面的备选答案。
setValue
对我不起作用。或者,您可以使用 reset
方法:
Reset either the entire form state or part of the form state.
这是工作代码:
/* 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]);
@tommcandrew 的 setValue 参数格式对我不起作用。
这种格式做了:
useEffect(() => {
const object = localStorage.getItem('object');
setValue("name", object.name);
}, [])
虽然这个 post 已有 2 个月大,但我今天偶然发现了这个问题并搜索了几种方法来解决这个问题。我想出的最有效的方法是使用 useMemo 来设置你的默认值,就像这样:
const { control, errors, handleSubmit } = useForm({
reValidateMode: 'onChange',
defaultValues: useMemo(() => yourDefaultValues, [yourDefaultValues]),
});
这允许您在表单中正确设置值,如果您碰巧有字段数组(我就是这种情况),则无需多次实现。
这在使用官方文档中的 advanced smart form component exemple 时也有效。如果您有任何问题,请告诉我!
@tam 的回答是使其与 6.8.3 版一起工作所需的一半。
您需要提供默认值,还要使用Effect来重置。如果您有一个用另一个实体重新加载的表单,则需要这种特殊区别。我在 CodeSanbox here.
中有一个完整的示例
简而言之:
您需要在 userForm
.
中定义默认值
const { register, reset, handleSubmit } = useForm({
defaultValues: useMemo(() => {
return props.user;
}, [props])
});
然后你需要倾听潜在的变化。
useEffect(() => {
reset(props.user);
}, [props.user]);
代码沙箱中的示例允许在两个用户之间交换并让表单更改其值。
这适用于嵌套对象(我使用的是版本 6.15.1)
useEffect(() => {
for (const [key, value] of Object.entries(data)) {
setValue(key, value, {
shouldValidate: true,
shouldDirty: true
})
}
}, [data])
找到另一个简单的方法,我使用 reset
API from useForm
const { handleSubmit, register, reset } = useForm({ resolver });
调用 API 并返回响应数据后,使用新的 apiData 调用 reset
,确保 apiData 键与输入键(名称属性)相同:
useEffect(() => {
reset(apiData);
}, [apiData]);
表单的默认值被缓存,因此一旦您从 API 获取数据,我们就会用新数据重置表单状态。
我正在创建一个页面供用户使用 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
状态。
{
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]);
您可以从表单中删除默认值。
编辑:如果这不起作用,请参阅下面的备选答案。
setValue
对我不起作用。或者,您可以使用 reset
方法:
Reset either the entire form state or part of the form state.
这是工作代码:
/* 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]);
@tommcandrew 的 setValue 参数格式对我不起作用。
这种格式做了:
useEffect(() => {
const object = localStorage.getItem('object');
setValue("name", object.name);
}, [])
虽然这个 post 已有 2 个月大,但我今天偶然发现了这个问题并搜索了几种方法来解决这个问题。我想出的最有效的方法是使用 useMemo 来设置你的默认值,就像这样:
const { control, errors, handleSubmit } = useForm({
reValidateMode: 'onChange',
defaultValues: useMemo(() => yourDefaultValues, [yourDefaultValues]),
});
这允许您在表单中正确设置值,如果您碰巧有字段数组(我就是这种情况),则无需多次实现。
这在使用官方文档中的 advanced smart form component exemple 时也有效。如果您有任何问题,请告诉我!
@tam 的回答是使其与 6.8.3 版一起工作所需的一半。
您需要提供默认值,还要使用Effect来重置。如果您有一个用另一个实体重新加载的表单,则需要这种特殊区别。我在 CodeSanbox here.
中有一个完整的示例简而言之:
您需要在 userForm
.
const { register, reset, handleSubmit } = useForm({
defaultValues: useMemo(() => {
return props.user;
}, [props])
});
然后你需要倾听潜在的变化。
useEffect(() => {
reset(props.user);
}, [props.user]);
代码沙箱中的示例允许在两个用户之间交换并让表单更改其值。
这适用于嵌套对象(我使用的是版本 6.15.1)
useEffect(() => {
for (const [key, value] of Object.entries(data)) {
setValue(key, value, {
shouldValidate: true,
shouldDirty: true
})
}
}, [data])
找到另一个简单的方法,我使用 reset
API from useForm
const { handleSubmit, register, reset } = useForm({ resolver });
调用 API 并返回响应数据后,使用新的 apiData 调用 reset
,确保 apiData 键与输入键(名称属性)相同:
useEffect(() => {
reset(apiData);
}, [apiData]);
表单的默认值被缓存,因此一旦您从 API 获取数据,我们就会用新数据重置表单状态。