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

React Hook Form:如何重置嵌套数组/对象脏状态且不影响其他字段

React Hook Form多步骤表单:重置特定嵌套字段脏状态问题

表单结构与需求

  • 表单为多步骤结构
  • 步骤3:选择演示相关主题
  • 步骤4:根据选中主题动态加载问题
  • 每个问题结构:
    • text字段(原始类型)
    • options数组,每个选项包含:
      • videos数组
      • text字段
  • 每个问题有独立保存按钮,保存后需仅重置该问题的所有字段脏状态,不影响表单其他部分。

示例表单数据

[
  {
    "options": [
      {
        "videos": [true],
        "text": true
      },
      {
        "videos": [true],
        "text": true
      }
    ],
    "text": true
  },
  {
    "options": [
      {
        "videos": [true],
        "text": true
      },
      {
        "videos": [true],
        "text": true
      }
    ],
    "text": true
  }
]

问题现状

通过resetField()编写递归函数重置已保存问题的脏字段:

  • ✅ 对原始类型字段有效
  • ❌ 无法重置数组和对象的脏状态

已尝试的递归函数

const clearNestedDirtyFields = (dirtyObj, basePath = '') => {
  Object.keys(dirtyObj).forEach(key => {
    const path = basePath ? `${basePath}.${key}` : key;

    if (Array.isArray(dirtyObj[key])) {
      dirtyObj[key].forEach((item, index) => {
        const itemPath = `${path}[${index}]`;

        if (item === true) {
          resetField(itemPath, { keepDirty: false, defaultValue: watch(itemPath) });
        } else if (typeof item === 'object' && item !== null) {
          clearNestedDirtyFields(item, itemPath);
        }
      });
    } else if (dirtyObj[key] === true) {
      resetField(path, { keepDirty: false, defaultValue: watch(path) });
    } else if (typeof dirtyObj[key] === 'object' && dirtyObj[key] !== null) {
      clearNestedDirtyFields(dirtyObj[key], path);
    }
  });
};

已执行的排查操作

  1. 添加日志验证函数能正确遍历嵌套字段 ✅
  2. 显式调用resetField(path, { keepDirty: false }) ✅
  3. 重置前调用setValue(path, watch(path)) ✅
  4. 确认resetField()对数组/对象脏状态无效 ❌

预期行为

保存单个问题时,仅清除该问题下所有字段(包括嵌套的options、videos)的脏状态,不影响其他问题或表单其他字段。


疑问

  • 如何通过resetField()重置嵌套数组/对象的脏状态,且不影响其他字段?
  • React Hook Form是否有更合适的替代实现方案?

脏值提取工具函数

export function getDirtyValues(dirtyFields, values) {
  return Object.keys(dirtyFields).reduce((prev, key) => {
    if (!dirtyFields[key] || values[key] === undefined) return prev;

    return {
      ...prev,
      [key]: typeof dirtyFields[key] === 'object' ? getDirtyValues(dirtyFields[key], values[key]) : values[key],
    };
  }, {});
}

内容的提问来源于stack exchange,提问作者Zain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 08:20:00