Consider the following code:
const ChildMemo = React.memo(Child); const Component = () => { return ( <ChildMemo> <div>Some text here</div> </ChildMemo> ); };
Let's say a state change happens in the Component
, will ChildMemo
re-render or not?
Click here to see the solution
The nice nesting syntax in JSX is really just sugar for passing a children
prop. For example, this code:
const Component = () => { return ( <ChildMemo> <div>Some text here</div> </ChildMemo> ); };
is equivalent to:
const Component = () => { return <ChildMemo children={<div>Some text here</div>} />; };
It behaves exactly the same. JSX elements are just objects created via React.createElement
. In this case, the <div>
is represented as an object like:
{ type: "div", // ...other properties }
From a memoization perspective, ChildMemo
receives a prop (children
) that is a new object on every render. This means React.memo
wonβt prevent re-renders.
To fix this, we need to memoize the div
itself using useMemo
:
const Component = () => { const content = useMemo(() => <div>Some text here</div>, []); return <ChildMemo children={content} />; };
Now the children
prop is stable, and React.memo
can effectively prevent unnecessary re-renders.
const ChildMemo = React.memo(Child);
const Component = () => {
return (
<ChildMemo>
<div>Some text here</div>
</ChildMemo>
);
};
const Component = () => {
return (
<ChildMemo>
<div>Some text here</div>
</ChildMemo>
);
};
const Component = () => {
return <ChildMemo children={<div>Some text here</div>} />;
};
{
type: "div",
// ...other properties
}
const Component = () => {
const content = useMemo(() => <div>Some text here</div>, []);
return <ChildMemo children={content} />;
};