React-Hook-Form:值为对象的Controller不触发dirtyFields更新问题
问题解决方法
1. 触发touchedFields更新
DatePicker可能未自动触发onBlur事件,导致RHF无法标记字段为已触碰。需手动在日期选择器关闭时调用field.onBlur:
return ( <Controller control={control} name={rName} rules={{ required: "وارد کردن این فیلد اجباری است" }} render={({ field: { onChange, value, onBlur } }) => ( <DatePicker value={value} calendar={persian} locale={persian_fa} format="YYYY-MM-DD" onOpenPickNewDate={false} calendarPosition="bottom-right" {...datePickerProps} onChange={(e) => { onChange(e); datePickerProps.onChange && datePickerProps.onChange(e); }} onClose={() => { onBlur(); // 手动触发blur事件,更新touchedFields datePickerProps.onClose && datePickerProps.onClose(); }} /> )} /> );
2. 确保值变化被RHF检测
React Hook Form依赖值的引用变化或可比较的差异来更新状态。如果DatePicker返回的DateObject引用未改变,可手动创建新实例:
onChange={(e) => { // 生成新的DateObject实例,确保RHF识别到值变化 const newDateObj = new DateObject(e); onChange(newDateObj); datePickerProps.onChange && datePickerProps.onChange(newDateObj); }}
3. 自定义值比较逻辑
如果上述方法无效,可通过valueComparer自定义DateObject的比较规则,替代默认的浅比较:
<Controller control={control} name={rName} rules={{ required: "وارد کردن این فیلد اجباری است" }} valueComparer={(prev, next) => { // 通过时间戳判断两个DateObject是否等价 return prev?.toJSON() === next?.toJSON(); }} render={({ field: { onChange, value, onBlur } }) => ( // 同上DatePicker代码 )} />
4. 规范默认值初始化
确保默认值在useForm的defaultValues中一次性设置,避免组件重复渲染时生成新实例:
const { control, ...rest } = useForm({ defaultValues: { my_input_8: toDateObject(new Date(defaultValues.my_input_8 || "")), }, });
验证方式
通过watch监听字段值,确认每次选择日期时输出新的DateObject实例:
const watchDate = watch(rName); console.log(watchDate);
内容的提问来源于stack exchange,提问作者Someone
相关产品推荐
相关产品推荐

