react-hooks-form搭配Material UI TextField实现关联字段时值未注册到data对象
问题根因
你出现这个问题的核心原因是没有将week字段的更新同步到react-hook-form的内部状态库:
- 你用外部useState维护的dateValue只更新了week输入框的展示值,但没有触发week字段Controller对应的onChange方法,react-hook-form感知不到这个字段的数值变更,提交时自然拿不到最新值
- 额外给week输入框加了disabled属性,也会默认阻止输入框的变更事件触发,进一步阻断了状态同步的路径
解决方案
不需要额外维护外部useState,直接用react-hook-form提供的setValue方法操作表单字段即可,修改步骤如下:
- 从useForm的返回值中解构出
setValue方法 - 删除冗余的
dateValueuseState变量 - 在date字段的变更回调中,计算完周数值后直接调用
setValue更新week字段 - week字段的TextField直接使用Controller返回的value绑定即可,不需要绑定外部状态
修改后的完整代码示例:
// 第一步:解构setValue const { handleSubmit, control, setValue } = useForm({}); // 删除原来的const [dateValue, setDateValue] = useState() const onSubmit = (data) => {console.log(data.week)} // 此时可以正常拿到值 const getWeekAndYear = (dateStr) => { // 这里替换成你自己实现的「周数-年份」计算逻辑即可 const date = new Date(dateStr); // ......你的计算逻辑 return `${week}-${year}` } return <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) => { const dateVal = event.target.value; onChange(dateVal); // 计算周数后直接更新week字段 const weekStr = getWeekAndYear(dateVal); setValue('week', weekStr); }} 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} // 直接绑定Controller返回的value即可 value={value} onChange={onChange} error={!!error} helperText={error ? error.message : null} /> )} /> </form>
内容的提问来源于stack exchange,提问作者Alex Bran
相关产品推荐
相关产品推荐

