结合 react-hook-form 从 MUI 更新 TextField。 onChange 未被调用
Update TextField from MUI in conjunction with react-hook-form. onChange is not being called
const [userData, setUserData] = useState({
fullName: "",
email: "",
}); // Local component state
const onChange = (event) => {
console.log(event.target.value);
}; // Evente handler
<Grid container spacing={1}>
<Grid item xs={12} sm={12}>
<TextField
required
id="name"
name="fullName"
onChange={onChange}
label="Name"
InputLabelProps={{ shrink: true }}
fullWidth
value={userData.fullName}
margin="dense"
/>
<Typography variant="inherit" color="textSecondary">
{errors.fullName?.message}
</Typography>
</Grid>
<Grid item xs={12} sm={12}>
<TextField
required
id="email"
name="email"
label="Email"
onChange={onChange}
fullWidth
margin="dense"
value={userData.email}
{...register("email")}
error={errors.email ? true : false}
/>
<Typography variant="inherit" color="textSecondary">
{errors.email?.message}
</Typography>
</Grid>
由于某种原因,没有调用 onChange。我还使用 Yup 进行验证。我需要更新输入值并将其发送到 API。但是由于某种原因没有调用事件处理程序
你正在用 {...register("email")}
的传播覆盖 onChange
属性,因为 register
调用将 return 一个对象,其中一个 属性 是名为 onChange
,RHF 需要更新它的内部表单状态。因此,当您使用 RHF 时,您根本不需要自己的 onChange
处理程序,因为您可以直接通过 RHF 访问当前的 <TextField />
值。您只需通过 useForm
defaultValues
传递您的默认值或直接将其传递给 <Controller />
而不是直接通过 value
属性设置它。
我还建议使用 <Controller />
,因为 register
您正在失去为 <TextField />
输入元素设置正确 ref
的功能通过 inputRef
属性链接,而不是使用 RHF register
使用的 ref
。当您希望在提交表单时验证失败时立即聚焦某个字段时,这会派上用场。
您还可以使用 <TextField />
的 error
和 helperText
道具来显示您的错误并通过 <Controller />
fieldState
对象访问它以获取当前验证错误(如果有的话)。
<Grid container spacing={1}>
<Grid item xs={12} sm={12}>
<Controller
control={control}
name="fullName"
defaultValue={userData.fullName}
render={({ field: { ref, ...field }, fieldState: { error } }) => (
<TextField
required
id={field.name}
label="Name"
InputLabelProps={{ shrink: true }}
fullWidth
margin="dense"
error={!!error}
helperText={error?.message}
/>
)}
/>
</Grid>
<Grid item xs={12} sm={12}>
<Controller
control={control}
name="email"
defaultValue={userData.email}
render={({ field: { ref, ...field }, fieldState: { error } }) => (
<TextField
required
id={field.name}
label="Name"
InputLabelProps={{ shrink: true }}
fullWidth
margin="dense"
error={!!error}
helperText={error?.message}
/>
)}
/>
</Grid>
</Grid>
const [userData, setUserData] = useState({
fullName: "",
email: "",
}); // Local component state
const onChange = (event) => {
console.log(event.target.value);
}; // Evente handler
<Grid container spacing={1}>
<Grid item xs={12} sm={12}>
<TextField
required
id="name"
name="fullName"
onChange={onChange}
label="Name"
InputLabelProps={{ shrink: true }}
fullWidth
value={userData.fullName}
margin="dense"
/>
<Typography variant="inherit" color="textSecondary">
{errors.fullName?.message}
</Typography>
</Grid>
<Grid item xs={12} sm={12}>
<TextField
required
id="email"
name="email"
label="Email"
onChange={onChange}
fullWidth
margin="dense"
value={userData.email}
{...register("email")}
error={errors.email ? true : false}
/>
<Typography variant="inherit" color="textSecondary">
{errors.email?.message}
</Typography>
</Grid>
由于某种原因,没有调用 onChange。我还使用 Yup 进行验证。我需要更新输入值并将其发送到 API。但是由于某种原因没有调用事件处理程序
你正在用 {...register("email")}
的传播覆盖 onChange
属性,因为 register
调用将 return 一个对象,其中一个 属性 是名为 onChange
,RHF 需要更新它的内部表单状态。因此,当您使用 RHF 时,您根本不需要自己的 onChange
处理程序,因为您可以直接通过 RHF 访问当前的 <TextField />
值。您只需通过 useForm
defaultValues
传递您的默认值或直接将其传递给 <Controller />
而不是直接通过 value
属性设置它。
我还建议使用 <Controller />
,因为 register
您正在失去为 <TextField />
输入元素设置正确 ref
的功能通过 inputRef
属性链接,而不是使用 RHF register
使用的 ref
。当您希望在提交表单时验证失败时立即聚焦某个字段时,这会派上用场。
您还可以使用 <TextField />
的 error
和 helperText
道具来显示您的错误并通过 <Controller />
fieldState
对象访问它以获取当前验证错误(如果有的话)。
<Grid container spacing={1}>
<Grid item xs={12} sm={12}>
<Controller
control={control}
name="fullName"
defaultValue={userData.fullName}
render={({ field: { ref, ...field }, fieldState: { error } }) => (
<TextField
required
id={field.name}
label="Name"
InputLabelProps={{ shrink: true }}
fullWidth
margin="dense"
error={!!error}
helperText={error?.message}
/>
)}
/>
</Grid>
<Grid item xs={12} sm={12}>
<Controller
control={control}
name="email"
defaultValue={userData.email}
render={({ field: { ref, ...field }, fieldState: { error } }) => (
<TextField
required
id={field.name}
label="Name"
InputLabelProps={{ shrink: true }}
fullWidth
margin="dense"
error={!!error}
helperText={error?.message}
/>
)}
/>
</Grid>
</Grid>