React Global Memoization

Viewed 536

I have the following React test app:

class MemoTestApp extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
     showOverlay: false,
    }
  }
  
  render() {
    return (
      <div>
        <div>
          <MemoComponent str="Hello World" />
        </div>
        <div>
          <input type="button" onClick={() => this.setState({showOverlay: true})} value="Show Overlay"/>
        </div>
        {this.state.showOverlay && (
          <div className="overlay">
            <h2>Overlay</h2>
            <MemoComponent str="Hello World" />
          </div>
        )}
      </div>
    )
  }
}

const Component = (props) => {
  console.info('render ' + props.str);
  return <div>{props.str}</div>;
}

const MemoComponent = React.memo(Component);

ReactDOM.render(<MemoTestApp />, document.querySelector("#app"))
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
  position: relative;
  min-height: 200px;
}

.overlay {
  position: absolute;
  padding: 20px;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background-color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

As you can see, there is a memoized functional component which is rendered twice with the same props. The first rendering takes place immediately, the second one after the user presses the button.

However, the component really is rendered twice, as you can see in the console. React.memo prevents the second rendering of the first instance of the component, but the second instance seems to "now know" that this component has already been rendered with the given props.

Is there a way to make Memoization "global", i.e. so that rendered outputs are shared between different instances of the component?

What is the reason that React.memo is not global by default?

1 Answers

Short answer: Components are reusable, this is by design.

They may have their own state, for example a counter. Or they have side effects, e.g. own intervals, custom logic depending on the DOM nodes.

For that reason, they have to be separate "instances" depending where they live on the DOM (parent node, index or key), and are separately rendered. The result is then memoized per component "instance".

Related