Why does reset rerender all useFormContext subscribers? #13013
|
Hi, I was wondering why calling reset function to clear form state is causing re-renders of all useFormContext subscribers? I have a button to clear my form. I thought I can use reset function, but all components using useFormContext (and useForm and consequently FormProvider) trigger re-render the moment I call reset function. I am looking for a way to clear my form state and I was able to write function, that walksthrough all my fields and calls
That solution does not cause any unnecessary re-renders. I was about to write some abstract solution/function to do this for any form provided. But I must say, this is too complicated and too frequent use case for me to be on correct path. So my question in - am I doing something wrong? Did I miss the correct approach somewhere along the way? |
Replies: 2 comments 1 reply
|
Please can somebody confirm the official stance on this issue? Or is anything needed from me? |
|
You're not doing anything wrong — this is how the context is wired.
// src/useFormContext.tsx
const memoizedValue = React.useMemo(() => ({ ...methods, formState }), [/* ..., */ formState, /* ... */])
Options, from least to most change: 1. const { resetField, getValues } = useFormContext()
const clear = () => {
Object.keys(getValues()).forEach((name) => resetField(name))
}It restores the default value and clears error/dirty/touched for that field only. 2. Don't read the whole context in leaf components. Grab function PriceField({ control }: { control: Control<FormValues> }) {
const { field, fieldState } = useController({ name: 'price', control })
// or: useWatch({ control, name: 'price' }) / useFormState({ control, name: 'price' })
return <input {...field} aria-invalid={!!fieldState.error} />
}
export default React.memo(PriceField)
3. Keep So: |
You're not doing anything wrong — this is how the context is wired.
FormProvidermemoizes the context value, butformStateis one of its dependencies:reset()updates the whole form state (values, dirty, touched, errors, submit count) in one go, so the component that ownsuseFormre-renders,formStategets a new reference, the context value changes, and every component that callsuseFormContext()re-renders.setValue+clearErrorsper field only notify the subscribers of that field, which is why your manual loop is quiet.Options, from least to most change:
1.
…