【React Hook Form】 Dirtyなvalues (変更されたフィールドの値) を取得する

const {
formState: { dirtyFields },
} = useForm({ ... });

React Hook FormでDirtyな (ユーザによって変更された) フィールドを参照する場合、useFormフックのformState.dirtyFieldsが利用できる。

しかしそれはあくまでフィールドの情報のみで、変更されたフィールドの値を取得するには自前実装が必要になる。

import type { FieldNamesMarkedBoolean, FieldValues } from 'react-hook-form';
export function getDirtyValues<T extends FieldValues>(
values: T,
dirtyFields: Partial<FieldNamesMarkedBoolean<T>>
): Partial<typeof values> {
return Object.keys(dirtyFields).reduce((prev, key) => {
const dirtyField = dirtyFields[key];
if (!dirtyField) return prev;
if (Array.isArray(dirtyFields)) return dirtyFields.map((_, i) => values[i] as T).filter(Boolean);
return {
...prev,
[key]: typeof dirtyField === 'object' ? getDirtyValues(values[key], dirtyField) : values[key]
};
}, {});
}

dirtyFieldsはネスト構造のため、再起的に探索する必要がある。

it('getDirtyValues', () => {
const result = getDirtyValues(
{
key1: 1,
key2: 2,
key3: 3,
key4: '4',
key5: true
},
{
key1: true,
key4: true,
key5: true
}
);
expect(result).toStrictEqual({
key1: 1,
key4: '4',
key5: true
});
});

1

参考
  1. https://github.com/orgs/react-hook-form/discussions/1991