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>
For some reason, onChange is not being called. I also using Yup for validation. I need to update the input value and send it to the API. But for some reason event handler is not being called
CodePudding user response:
You're overriding the onChange
prop with the spread of {...register("email")}
as the register
call will return an object, where one property is named onChange
, which RHF needs to update it's internal form state. Because of that you simply don't need your own onChange
handler when you use RHF, as you could just access the current <TextField />
value via RHF directly. You just have to pass your default values either via useForm
defaultValues
or pass it to <Controller />
directly instead of setting it via the value
prop directly.
I would also recommend to use <Controller />
as with register
you are losing the functionality of setting up the correct ref
for your <TextField />
input element as it is linked via the inputRef
prop instead of using ref
which RHF register
uses. This comes in handy when you want to instantly focus a field when validiation fails upon submitting the form.
You can also use <TextField />
's error
and helperText
props to display your error and access it via the <Controller />
fieldState
object to get the current validation error (if there is one).
<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>