reactjsreact-nativereact-memo

React Native how to use React.memo on every component from collection to render only changed ones. Strange behavior of React.memo


I have been trying to improve rendering performance by using React.memo on components. It works properly until I use it on every single component from the collection being inserted as children.

I prepared snack HERE

To understand what is going on you need to open the console because there are some logs presented. You will see WrapperMemo which generally renders Child components (they are also wrapped in some auxiliary components to check something I will explain later).

When you press the first button named SLICE MYNUMBERS you will see that React.memo's isEqual function called isWrapperEqual returns true, but it still does not stop from rerendering Child components. However neither Wrapper nor all other auxiliary wrapper components (ChildOk) are rendered!

When you click any PRESS ME:[number] button it forces you to re-render other Child components when only one is being modified.

It is worth mentioning that TestCompMemo is never re-rendered when any of the buttons are pressed - which is correct behavior.

1) Is there any explanation for that?

2) Is there a way to use React.memo on every component from collection to render only changed ones (as it is presented in Wrapper component) ?


Solution

    1. Is there any explanation for that?

    In your snack example, you have a Context.Provider wrapper at the top level of the application.

    This is what causes the re-render. This is expected behavior and you can read more about it here: https://github.com/facebook/react/issues/15156#issuecomment-474590693

    1. Is there a way to use React.memo on every component from collection to render only changed ones (as it is presented in Wrapper component) ?

    Using React.memo on every component is not recommended. You can run into bugs where components do not re-render and you are adding overhead with all the comparisons.

    If you want to optimize the application, you might want to run the profiler and figure out which parts of the app is slowing things down and work from there.

    But if you want to prevent unnecessary re-renders, you could move context usage up a few levels and pass the onPress to the child components.