Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What makes React.memo unreliable for preventing renders?

Tags:

reactjs

In the documentation for React.memo, it says:

This method only exists as a performance optimization. Do not rely on it to “prevent” a render, as this can lead to bugs.

I don't really understand this warning. Why can it not be relied on? How is it an optimization if it doesn't necessarily prevent renders?

I wish they had gone more into depth here, but since they didn't, can someone elaborate on this? As is, I feel reluctant to use it at all because this warning makes its behavior seem very unclear.

like image 947
temporary_user_name Avatar asked Mar 26 '19 03:03

temporary_user_name


2 Answers

Perhaps, we should consider this quote from official docs about the similar useMemo function:

You may rely on useMemo as a performance optimization, not as a semantic guarantee.

In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without useMemo — and then add it to optimize performance.

I believe the same could apply to React.memo and to useCallback hooks so you can't 100% rely on that React won't "forget" some memorized prop to free some memory.

like image 192
GProst Avatar answered Sep 30 '22 20:09

GProst


If the Parent component is passing a function (specifically, a function that updates the state of the Parent) down to the Child component, only using React.memo will not work. The function in the Parent component will need to be wrapped with the useCallback hook. This is because the function will be "re-rendered" every time the Parent re-renders, so the Child will always consider that function a new prop.

Read more on this here

Here is another interesting discussion I found regarding React.memo

Also React.memo is for functional components what React.PureComponent is for class components.

PureComponent handles shouldComponentUpdate method by default (shallow comparison).

shouldComponentUpdate basically tells react whether reconciliation is needed or not. If it is true then react compares the newly returned element with the previously rendered one using its diffing algorithm and based on the comparison it will update the DOM. There may be a case when the component was reconciled but rendered react elements were same so no DOM changes happened.

To get a clear picture for above have a look at this diagram

I think basis on above we can say that React.memo also tells us whether render cycle should run for a component. Actual DOM changes depends upon the diffing algorithm that react does to update the DOM.

like image 32
Utsav Patel Avatar answered Sep 30 '22 19:09

Utsav Patel