I bumped across a curiosity of where React.memo behaves as expected today.
It seems that React.memo doesn't work in nested functional components, but does work in the components main return and in nested functions that return a React.memo component.
Is this intended behaviour or is there another way to make React.memo work with nested functional components?
https://codesandbox.io/s/sweet-bhaskara-kbnlg?file=/src/memoTest.js:0-451
const MemoTestBase = ({ name, counter }) => {
console.log("rendering", name);
return (
<div className="">
<p>
{name}: {counter}
</p>
</div>
);
};
function areEqual(prevProps, nextProps) {
const isEqual = prevProps.name === nextProps.name;
if (isEqual) {
console.log("stopping", prevProps.name);
}
return isEqual;
}
const MemoTest = React.memo(MemoTestBase, areEqual);
const { useState } = React;
function App() {
const [counter, setCounter] = useState(0);
function funOne() {
return <MemoTest name="inside function" counter={counter} />;
}
const ComponentOne = () => {
return <MemoTest name="inside component" counter={counter} />;
};
return (
<div className="App">
<h1>React.memo render test</h1>
<p>Count: {counter}</p>
<button onClick={() => setCounter(counter + 1)}>Count + 1</button>
<hr />
<p>Memo tests</p>
<MemoTest name="root" counter={counter} /> {/* works! */}
<ComponentOne /> {/* doesn't work */}
{ComponentOne()} {/* works! */}
{funOne()} {/* works! */}
</div>
);
}
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>