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
textfield (primitive type). - An
optionsarray, where each option contains:- A
videosarray. - A
textfield.
- A
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],
};
}, {});
}