Wit Form

Performance

Wit Form is fast by default: changing a field re-renders that field and the components watching it, nothing else. You don't need React.memo or careful prop drilling. This page explains the few things that can undo that, and the options for very large forms.

See the Render Performance example: a table of up to 2,000 inputs with render counters on every cell.

What re-renders when a value changes

ComponentRe-renders?
The field you typed in (useField)Yes
Other fieldsNo
Components watching that field (useFieldWatch, column watches)Yes
Components watching other fieldsNo
The component that calls useFormNo
A component that calls useFieldArray without validateNo, only when rows are added or removed
A component that calls useFieldArray with validateYes, for any change in its rows
Components using useFormValues, useFormValuesAndExtraInfos or useIsDirtyYes, for any change

Tips

Watch in small components. Call watch hooks in the smallest component that shows the value, not in the form component. See Watching Values.

Read in event handlers, don't watch. If a value is only needed when something is clicked, read it with getValue or getValues from useFormContext. Reading doesn't subscribe to anything.

Validate large arrays at the form level. A field array validate subscribes to every value in the array. For a table with hundreds of rows, leave it out and check the rows in useForm's validate, which only runs on submit.

Keep functions and arrays stable. Define validators outside components, or memoize them. Memoize ancestors arrays with useMemo. New objects on every render make hooks redo work.

Use useFormValues sparingly. It re-renders on every keystroke anywhere in the form. That's fine for a small debug panel, but not for a component that renders a lot.

Turning off whole-form tracking

To keep useFormValues and useIsDirty live, each FormProvider tracks the values of the whole form. On very large forms that don't use those two hooks, turn it off:

<FormProvider options={{ skipValuesObserver: true }}>
  <BigSpreadsheet />
</FormProvider>

With this option, useFormValues, useFormValuesAndExtraInfos and useIsDirty stop updating. Everything else, including submit, validation, getValues and checkIsDirty(), still works.

On this page