reactjsmemo

use React.memo with mapped collection


Somehow the react.memo (or the hook version) wont work when the components are "generated" by a map.

code example: https://codesandbox.io/embed/react-memo-example-iuqf4

const Item = ({ step }) => <div>{step.name}</div>;
const MemoItem = React.memo(Item, (prevProps, nextProps) => {
  console.info("memo"); //no console
  if (prevProps.show === nextProps.show) {
    return true;
  }
  return false;
});

const initialSteps = [{
    name: "Pim",
    show: true
  }, {
    name: "Christa",
    show: false
  }, {
    name: "Henk",
    show: true
  }, {
    name: "klaas",
    show: true
  }];

{steps.steps.map((step, 
    <MemoItem key={index} step={step} />
))}

My expectation is that every rendered Item get "memoized" (and show a log in a console).


Solution

  • It is working as expected. The equality comparison function only runs on renders AFTER the first render. There's nothing to "compare" props to on the first render because that's when it is being memoized. So you don't see the "memo" log in console - it renders once, but the App component doesn't re-render, so the comparison function does not get called.

    Try adding a simple state update to your app component to force a re-render. You'll see the "memo" lines in console, however the memoized component functions will not run because they have been successfully memoized.

    class App extends Component {
      render() {
        const { steps } = this.props;
        return (
          <div onClick={() => {
            this.setState({ time: Date.now() })
          }}>
            {steps.steps.map((step, index) => (
              <MemoItem key={index} step={step} />
            ))}
          </div>
        );
      }
    }
    

    Edit: I will point out that it is almost certainly pointless for you to make this optimization. React.memo exists for very limited cases where component re-renders are causing serious performance problems. Perhaps you are doing this as an exercise in learning React, but in the vast majority of cases, React's own internal optimizations are more than sufficient. Premature optimization is bad!