Home > Software engineering >  Why aren't all React components wrapped with React.memo() by default?
Why aren't all React components wrapped with React.memo() by default?

Time:10-11

I've just learned about React.memo() and was wondering, when would we NOT want that behavior? Wouldn't we always want components to only re-render if their props have been changed?

CodePudding user response:

It's because the memoization itself is not free and you shouldn't use it everywhere. Because:

  • Memoization itself incurs a perf cost in comparing values from one render to the next. In some cases this actually might be larger than the cost of render.
  • You can't write a universal comparison function that will work in every single case. The second argument to react memo is important. The developer defines there in what specific changes to props should the component rerender. This is often more complex than simple 1:1 prop changes in 2 respects. Firstly, the value to compare may not be something that can be easily compared (like a string or int), but complex objects or references to functions etc. Secondly, you may only want the rerender to happen when a certain combined set of prop changes happens. So by enabling it everywhere, you'd be asking devs to think about this for every single component in their system which would be a very large and error-prone task. It would also be, probably, for very little gain on most components. You should only do all this when you have a problem to solve.
  • Memoization is useful when you have a perf problem, but until you do its a bad idea to use it since it also greatly increases the surface area for bugs in your application. If you compare a prop incorrectly, or in the case of useMemo, forget to add something to the deps array -- your app now has a bug in it. Since this is a developer managed thing -- human error occurs. This typically happens a lot when an unsuspecting dev expands the API of the memoized component then doesn't update the comparison function. The exact opposite can also happen where the memoization function has been written in such a way that it will accept and compare new props without changes, but that comparison (like if its comparing an object, it will be a diff reference each time) actually ends up triggering a rerender every time anyway making the whole thing pointless (false sense of security).

In short: memoization is a maintenance burden and you should only take that on with a cost-benefit analysis in individual and specific circumstances.

  • Related