-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
onChange
reference can cause performance issues
#1804
Comments
It looks like we should be able to use https://reactjs.org/docs/hooks-faq.html#how-to-read-an-often-changing-value-from-usecallback |
Having the same issue when using How are you guys working around this? I can't use |
Can someone submit a PR? |
Yeah we should fix this. All handleX should use event callback. |
🚀 Feature request
Make
onChange
have the same reference between rendersCurrent Behavior
Currently, the
onChange
that gets "generated" and passed to a component via<Field>
gets a difference reference on every render. Due to that, the component rendered fromField
gets a prop with different reference on every render, which causes the component to be re-rendered regardless of the use ofmemo
in it.For example, let's suppose we have a Formik form which contains the following:
<Field as={Combobox} name="combobox" />
Any time any field gets rendered (not necessarily this one), the
onChange
prop that gets automatically passed to theCombobox
gets a different reference. Thus, even if theCombobox
implements aReact.memo()
it will have to re-render since its props changed.On big forms or forms with a lot of styled components within them (a.k.a. loads of context consumers) this causes performance issues.
Desired Behavior
Ideally, we would want the
onChange
prop passed to components whose values have not changed to be referentially the same as the one in the previous render cycle. This way, the component which amemo
won't render unnecessarily.Suggested Solution
This issue doesn't happen with
onBlur
(which always keeps the same reference), but only withonChange
. Seeing the code I see that it gets a new reference every time theexecuteChange
function changes referenceformik/src/Formik.tsx
Line 545 in 44afb37
The latter changes reference every time any of the values changes
formik/src/Formik.tsx
Line 483 in 44afb37
This is reference change happens only to cover the
checkboxes
caseformik/src/Formik.tsx
Line 521 in 44afb37
state.values
has been added to theuseCallback
array for something specific that doesn't necessarily apply to all forms out there.Ideally we would want to handle this case differently. Perhaps separate the
executeChange
for the checkboxes case and keep the existing one for everything else?To be fully honest, I might be missing something big here, so any info will be extremely helpful. At the end of the day, my goal is to have the
Combobox
(in the above example) not re-render when a value unrelated to it changes.Who does this impact? Who is this for?
All users, but mainly projects with complex and/or heavy forms
P.S. Cheers for everything. Really appreciate the time you throw in this OSS.
The text was updated successfully, but these errors were encountered: