Search code examples
reactjsreact-contextreact-memo

Child component is still re-rendered even if it is not consuming the context


I have the following structure in my React code:

const Parent: React.FC<ParentProps> = (props) => {
    const [value1, setValue1] = useState<any>(null);

    return (
        <div>
            <SomeContextProvider
                contextElem1={value1}
                contextElem2={value2}
            >
                ...some code here

                <Child
                    prop1={value3}
                    prop2={value4}
                />
            </SomeContextProvider>
        </div>
    );
}
 
export default Parent;
const Child: React.FC<ChildProps> = ({ prop1, prop2 }) => {
    return (
        <div>
            {prop1} {prop2}
        </div>
    );
}
 
const propsAreEqual = (prevProps: ChildProps, nextProps: ChildProps) => {
    return true;
}


export default React.memo(Child, propsAreEqual);

As you notice:

  • Child component does not consume SomeContext
  • Child component is only wrapped with SomeContextProvider (does this mean that the child is consuming the context?)

Here is the scenario:

  • When Parent is re-rendered, the Child is also re-rendered even if the Child does not consume the SomeContext and propsAreEqual returns true.
  • When I move Child to outside scope, React.memo works as expected and prevents re-rendering of Child when Parent is re-rendered.

How come Child is re-rendered while it is not consuming the context? Isn't React.memo supposed to prevent re-renders? What do I miss about these concepts?


Solution

  • I think you are mistaken. I copied your code into a CodeSandbox and modified it so it actually builds. The child does not render whenever the parent re-renders, because you've wrapped it in React.memo(). (If I remove the memo() then the child does re-render.)

    https://codesandbox.io/s/misty-feather-tl3p6?file=/src/App.js

    If your code is triggering re-renders, it might be because of your specific implementation of the propsAreEqual function or the values you are passing for value3 or value4.