inertiajs / inertia

Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers.
https://inertiajs.com
MIT License
6.53k stars 433 forks source link

Optimizing useForm in Inertia.js: Preventing Unnecessary Re-renders #2084

Open HassanDev13 opened 1 week ago

HassanDev13 commented 1 week ago

Version:

Describe the problem:

I'm encountering a performance challenge with the useForm hook in Inertia.js while rendering a form with initial data in the following structure:

{
  a: 0,
  b: 0,
  c: true
}

The issue arises when modifying one input component; it triggers a re-render of all form components. While this behavior is manageable with small forms, it poses a performance concern for larger, more complex forms.

Could you provide guidance on optimizing useForm to prevent unnecessary re-renders or suggest any best practices to improve performance in this context?

Steps to reproduce:

1 - Set up Inertia.js with React:

Install Inertia.js and @inertiajs/react version 1.0.0 in your project. Create a simple page component using useForm.

2 - Define Initial Form State:

Use useForm to initialize form data with a structure like the following:

const { data, setData } = useForm({
  a: 0,
  b: 0,
  c: true
});

3 - Render Multiple Input Components:

Set up three input components to bind each of the fields (a, b, c) from the form state, for example:

<input
  type="number"
  value={data.a}
  onChange={(e) => setData('a', e.target.value)}
/>
<input
  type="number"
  value={data.b}
  onChange={(e) => setData('b', e.target.value)}
/>
<input
  type="checkbox"
  checked={data.c}
  onChange={(e) => setData('c', e.target.checked)}
/>

4 - Observe Component Re-renders:

Use React DevTools to monitor re-renders. Change the value of one input (e.g., data.a) and observe that all input components are re-rendered each time an individual field updates.

5 - Test with Additional Fields:

To simulate a complex form, expand the initial form state with additional fields (e.g., d, e, f, etc.) and repeat step 4. The re-renders should increase, causing noticeable performance degradation as the form grows.

Hasan-Mir commented 2 days ago

This behavior is due to React, not Inertia. To prevent unnecessary re-renders, consider wrapping the inputs in a custom Input component. Memoize this component with React.memo and use useCallback for the onChange handlers.

HassanDev13 commented 2 days ago

True, it’s a React issue, but the useForm hook provided by Inertia can handle this similarly to how React Hook Form does.