Search code examples
javascriptreactjsreact-state-managementreact-context

React sub component changes one property in a root state object - will all sub components render or not?


Note, I changed the description of my question a bit. The state is an object with many properties, not an array. Even though if it were an array, the question would still hold and be similar...

I'm developing a react web application. The root component has a state variable called user. user has many properties and each sub component only uses a subset of them. I'm thinking of using the react context API plus Memo to let all the sub components have access to user. I've read that using Memo will cause only the changed sub components to render and not all of them. But I'm unsure if I'm implementing all of this correctly and perhaps all the subcomponents WILL render?

A scenario that will happen is that one of the sub components makes a change to one of the properties in user and calls set_user(newUserWithOnePropertyUpdated) in the root component. So will all sub components render or only the ones that need to?


Solution

  • I think in your case the sub-components will re-render, even when using React.memo().

    re-render

    A component re-renders, if a passed property is not referentially equal to the one in the previous render.

    So, if you pass your user-object to the sub-components props, and the user-object is not the same one that it was before, all the sub-components re-render, even if you use React.memo().

    In React you usually will update a state by replacing the whole object, so the user-object will always be a new one, and all sub-components using the user-object will re-render (even with React.memo()).

    To avoid re-render with React.memo, you can:

    • Only pass primitive values to the props (e.g. strings or numbers).
    • Split your users-object into smaller object, which only change if the sub-component should also change, and pass these smaller objects to the sub-components props (the user-object may still hold references to these smaller objects).
    • use the second parameter of React.memo( component, isEqual ), to manually define what should be considered "a change".

    optimize or not

    However, without knowing your exact use case, it might not be necessary to optimize with React.memo(), as React is efficient in "re-rendering": it might re-render the component structure (which is fast), but not the visible DOM tree (which is slow).

    React.memo() usually becomes important only if very many components have to be re-rendered, or very often (renders per time).