What are you on about?
When writing React with hooks, I've seen a lot of properties of functional components go un-memoized. In my opinion, this is almost always a no-no.
This is generally not a good practice because of how React works. Anything that is not memoized is redefined on every re-render. So in general, my rule is to memoize everything defined in the functional component and move everything else out of the component into the global scope.
Not only does this speed up the performance of the thing that you defined, but not doing this has a compounding effect. If the thing you forgot to memoize is depended on (meaning in the dependency array of useMemo or useCallback) by another property, that property will be redefined on every render as well.
Variables that are defined globally do not get redefined when re-renders happen so they can be used without worrying about causing redefinitions.
Say what?
Here is a nice before example from a personal project (ignore what is/isn't defined as far as imports):
const { Title } = Typography;
const UserScreen = () => {
const db = firebaseApp.firestore();
const { user, logout } = useContext(AuthContext);
const onSubmit =
async (newUserProperties) => {
return await db
.collection(DB.COLLECTIONS.USERS)
.doc(user.uid)
.update(newUserProperties);
}
return (...);
};
In this case, the firebaseApp.firestore()
operation would be called on every render. Not fun. And then even if we threw the onSubmit
function in a useCallback with db in the dependency array, that would be redefined on every render as well. So you don't even get credit for almost doing it right!
Prove it
Here is a codesandbox that illustrates my point: https://codesandbox.io/s/relaxed-pasteur-7spqq?file=/src/App.js
Photo by Max Frajer on Unsplash
Top comments (5)
I'm gonna have to disagree. That's premature optimization, and potentially a cure worse than the disease in terms of memory overhead. Reach for useMemo and/or useCallback when rerenders are causing perf issues, and look to things like more localized context (if you're using it), offloading expensive computations to web workers, etc. first.
The Kent C. Dodds article @exclipy shared is an excellent resource, BTW.
On your codesandbox: you should remove the useCallback. It's not doing anything but overhead.
i would think not using useCallback creates overhead, without it every render the function is recreated
Also with it, the function is created on every render. See kentcdodds.com/blog/usememo-and-us...