With react-hooks-form I am trying to update one field based on another field value. The error I am facing is that my value is not registered in the data object.
This is my code:
const { handleSubmit, control } = useForm({});
const [dateValue, setDateValue] = useState()
const onSubmit = (data) => {console.log(data.week)} \\ undefined
<form
className={classes.root}
autoComplete="on"
onSubmit={handleSubmit(onSubmit)}
>
<Controller
name="date"
control={control}
defaultValue={props.operation === 'edit' ? props.values.date : null}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
id="date"
type="date"
label="date"
value={value}
className={classes.textField}
onChange={(event) => {
onChange(event.target.value);
setDateValue(event.target.value);
}}
error={!!error}
helperText={error ? error.message : null}
InputLabelProps={{
shrink: true,
}}
/>
)}
rules={{ required: 'Date is required' }}
/>
<Controller
name="week"
control={control}
defaultValue=""
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
id="week"
type="text"
className={classes.textField}
label="week"
disabled={true}
value={dateValue}
onChange={onChange}
error={!!error}
helperText={error ? error.message : null}
/>
)
/>
</form>
Finally, my week value is the result of a function which returns a string containing week - year concatenation.
The value is updated in the TextField, but it is not registered in the data object. Any idea what am I missing?
CodePudding user response:
On the onChange
handler of the date
field you are updating only the state of dateValue
and not the state of the form itself.
You have 2 options:
in the
onChange
handler of the date field call thesetValue
method you get fromuseForm
watch the value of the date field
const date = watch('day')
and have auseEffect
to update the value of the week field:
const {watch, setValue} = useForm()
const date = watch('date')
useEffect(() => {
const calculateWeekValue = () => {...//}
setValue('week', calculateWeekValue(date))
}, [date, setValue])
CodePudding user response:
You can use RHF's setValue
method for updating a field and call it inside the onChange
handler of your first <TextField />
.
So there is no need to use useState
here for managing he state of your first <TextField />
.
export const Demo: React.FC = () => {
const { control, handleSubmit, setValue } = useForm();
const onSubmit = (data) => console.log(data);
return (
<form autoComplete="on" onSubmit={handleSubmit(onSubmit)}>
<Controller
name="date"
control={control}
defaultValue={""}
render={({ field: { ref, ...field }, fieldState: { error } }) => (
<TextField
{...field}
onChange={({ target: { value } }) => {
field.onChange(value);
setValue("week", getWeek(new Date(value)));
}}
id="date"
type="date"
label="date"
error={!!error}
inputRef={ref}
helperText={error?.message}
InputLabelProps={{
shrink: true
}}
/>
)}
rules={{ required: "Date is required" }}
/>
<Controller
name="week"
control={control}
defaultValue={""}
render={({ field: { ref, ...field }, fieldState: { error } }) => (
<TextField
{...field}
id="week"
type="text"
label="week"
inputRef={ref}
error={!!error}
helperText={error?.message}
/>
)}
rules={{ required: "Date is required" }}
/>
<input type="submit" />
</form>
);
};