You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 10:20:17