如何解决反应钩子形式:OnSubmit 给我重置的值注册无效
React Hook Form 和 Material UI 有一个问题让我头疼。
我有一个用于创建和更新用户的表单以及一个使用 React Hook 表单的验证。有我的代码:
const [user,setUser] = useState({})
const schema = yup.object().shape({
email: yup.string().email().required("Email required"),})
const { register,handleSubmit,reset,formState: { errors } } = useForm({
mode: "onChange",reValidateMode: 'all',resolver: yupResolver(schema),defaultValues: user
})
useEffect(() => {
fetch(`localhost/api/user/${ route.params.userId }`).then(async r => {
let userDatas = await r.json()
setUser(userDatas)
})
},[route.params.userId])
useEffect(() => {
if( route.params.userId && Object.keys(user).length ) {
reset(user)
}
},[user])
const onSubmit = async (datas) => {
console.log(datas)
}
const handLeverifyDuplicate = async => {
//This function check that the email is not yet used in the database
}
return (
<form autoComplete="off" novalidate onSubmit={handleSubmit(onSubmit)}>
<TextField
name="email"
label="Email"
margin="dense"
variant="outlined"
required
{ ...register("email") }
onChange={(event) => {
register('email').onChange(event)
handLeverifyDuplicate(event)
}}
defaultValue={user && user.email}
/>
<Button
id="btn-save"
variant="contained"
color="primary"
size="small"
startIcon={<SaveIcon />}
type="submit"
>Save</Button>
</form>
)
所以,在创作上它就像一个魅力,但在版本上......
如果我更改电子邮件输入然后提交表单,则onSubmit函数中的console.log给我初始值用户电子邮件,而不是我刚刚输入的新电子邮件...
如果我删除了重置方法,前面的问题就解决了...但是如果我提交表单而不更改任何内容(onChange未触发),它告诉我它是必需的(当作为一个版本时,该值存在于输入中但未被验证检测到)
感谢您的帮助
解决方法
您的两个问题都是由于您没有使用 RHF 的 <Controller />
组件的问题:对于像 Material UI 的 <TextField />
这样的外部受控组件,您必须使用它,因为现在 RHF 有没有机会将 <TextField />
链接到它的表单状态,因为 register
不与外部受控组件一起工作。查看文档中的此 section 以了解更多信息。
const schema = yup.object().shape({
email: yup.string().email().required("Email required"),});
const {
control,handleSubmit,reset,formState: { errors },} = useForm({
mode: "onChange",reValidateMode: "all",resolver: yupResolver(schema),});
useEffect(() => {
fetch(`localhost/api/user/${route.params.userId}`).then(async (r) => {
let userDatas = await r.json();
reset(userDatas);
});
},[route.params.userId]);
const onSubmit = async (datas) => {
console.log(datas);
};
const handleVerifyDuplicate = (async) => {
//This function check that the email is not yet used in the database
};
return (
<form autoComplete="off" noValidate onSubmit={handleSubmit(onSubmit)}>
<Controller
name="email"
control={control}
render={({ field: { onChange,value } }) => (
<TextField
name="email"
label="Email"
margin="dense"
variant="outlined"
required
value={value}
onChange={(event) => {
handleVerifyDuplicate(event);
onChange(event);
}}
/>
)}
/>
<Button
id="btn-save"
variant="contained"
color="primary"
size="small"
startIcon={<SaveIcon />}
type="submit"
>
Save
</Button>
</form>
);
我认为您也不需要第二个 useEffect
,因为您可以在从 API 获取用户数据后使用 RHF reset
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。