I've created a very simple example here..
https://codesandbox.io/s/react-memo-with-function-props-09fgyo
As you can see, ComponentB
renders just as many times as ComponentB
.. even though it's wrapped in memo
and isn't receiving counter
as a prop.
If you open up the app in it's own page (https://09fgyo.csb.app/) and then use React DevTools to profile the page, you'll see that it's reporting it's cause for rendering is because the onClick
prop changes (see screenshot)
So.. I know the reason that's happening is because whenever the HOC's state is changed, it re-renders itself, and in doing so, creates a new handleButtonClick
because it's an arrow function. So React looks at that and says, "oop.. it's a new function, rerender ComponentB
!"
My question is.. what's the best pattern for fixing this kind of performance issue?
I mean.. I guess I could pass setCounter
down into CompnentB
, but that just seems icky.. tightly couples the HOC and it's state to ComponentB
. (Update: Now that I think about it, can't do that either because I'd have to pass down counter
as well in order to calculate the increment, and since that's changing, it would also cause a rerender.. ugh.)
I'm seriously at a loss.. Anyone have any ideas?
You can use useCallback
hook to wrap the function you pass to a child.
It will memoize the function and use the cache instead of recreating the function if none of the useCallback
array dependency change.