React 挂钩形式:OnSubmit 给我重置值(注册无效)
React hook form : OnSubmit give me the reseted values (register has no effect)
我有一个问题让我头疼 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>
)
所以,在创作上它很有魅力,但在版本上...
如果我更改电子邮件输入,然后提交表单,console.log在onSubmit函数中给我用户邮箱的初始值,不是我刚输入的新的...
如果我去掉reset方法,之前的问题就解决了...但是如果我提交表格而不改变任何东西( onChange 未触发),它告诉我它是必需的(当作为一个版本时,该值存在于输入中但未被验证检测到)
你有解决这两个问题的方法还是我做错了什么?
感谢您的帮助
你的两个问题都是因为你没有使用 RHF 的 <Controller />
组件:对于像 Material UI 的 [=12= 这样的外部控制组件] 你必须使用它,因为现在 RHF 没有机会 link <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.[=18 获取用户数据后使用 RHF reset
=]
我有一个问题让我头疼 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>
)
所以,在创作上它很有魅力,但在版本上...
如果我更改电子邮件输入,然后提交表单,console.log在onSubmit函数中给我用户邮箱的初始值,不是我刚输入的新的...
如果我去掉reset方法,之前的问题就解决了...但是如果我提交表格而不改变任何东西( onChange 未触发),它告诉我它是必需的(当作为一个版本时,该值存在于输入中但未被验证检测到)
你有解决这两个问题的方法还是我做错了什么?
感谢您的帮助
你的两个问题都是因为你没有使用 RHF 的 <Controller />
组件:对于像 Material UI 的 [=12= 这样的外部控制组件] 你必须使用它,因为现在 RHF 没有机会 link <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.[=18 获取用户数据后使用 RHF reset
=]