1

I am working on a multi-step form using React Hook Form, and I need to reset the dirty state of specific fields dynamically.

Form Structure:

  • The form is split into multiple steps.
  • In Step 3, I fetch topics related to a demo.
  • In Step 4, I fetch questions dynamically based on the selected topic.

Each question contains:

  • A text field (primitive type).
  • An options array, where each option contains:
    • A videos array.
    • A text field.

Each question is saved individually, and after saving, I want to reset its dirty state without affecting the rest of the form.


Example Form Data:


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

On my UI, each question has its own Save button. When saving, I want to clear the dirty fields for that specific question only.

Issue:

I created a recursive function using resetField() to reset only the dirty fields of the saved question.

✅ It works for primitive fields.
❌ But it does not reset the dirty state for arrays and objects.


Function Attempt:

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);
    }
  });
};

What I Have Tried:

1️⃣ Adding logs to verify that the function correctly processes the nested fields ✅
2️⃣ Using resetField(path, { keepDirty: false }) explicitly
3️⃣ Using setValue(path, watch(path)) before resetting
4️⃣ resetField() works fine for primitive fields, but does not clear arrays or objects


Expected Behavior:

When I save a question, only that question’s fields (including nested options and videos) should have their dirty state reset, without affecting other questions or fields in the form.

Question:

  • How can I reset the dirty state for nested arrays and objects using resetField() without affecting other fields?
  • Is there an alternative approach in React Hook Form to achieve this?

Additional Utility Function (For Dirty Values Extraction)

I am using the following function to get dirty values:

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],
    };
  }, {});
}

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.