I've been reading about React.memo and how it prevents re-renders by doing a shallow comparison of props. It sounds like a great way to optimize everything, but I've heard some developers say you shouldn't use it everywhere. If it makes things faster, why shouldn't I just wrap every single component in my application with it?
3 answers
The reason we don't use it everywhere is that React.memo itself has a performance cost. Every time a parent re-renders, React has to perform a shallow comparison of the new props against the old ones. For small components with simple props, this comparison might actually take longer than just re-rendering the component! You should reserve it for components that are "heavy"—those that have complex calculations, large sub-trees, or are rendered in long lists. Always use the React Profiler first to see if a component is actually a bottleneck.
Does the shallow comparison handle nested objects correctly, or do we need a custom comparison function for that?
Optimization should be a response to a problem, not a default setting. Only use it when you notice lag in specific UI parts.
Exactly, Susan. Premature optimization is the root of all evil in coding. I learned that the hard way by bloating a simple landing page with unnecessary memoization.
Great question, Matthew. By default, it only does a shallow check. If you pass a nested object as a prop, React.memo will think it's a new object every time because the reference changes, even if the values inside are the same. In that case, you either need to provide a custom comparison function as the second argument to React.memo, or better yet, use the useMemo hook in the parent component to memoize the object itself so the reference stays stable across renders.