Karl Stefan
Karl Stefan

Reputation: 160

React.memo behaviour

Consider the following simple components:

import React, { Fragment, memo } from 'react';

function Parent(props) {
  return (
    <Fragment>
      <Child {...props} />
      <Child foobar={props.foobar} />
    </Fragment>
  );
}

export default memo(Parent);
import React, { memo } from 'react';

function Child({ foobar }) {
  return (
    <p>{foobar}</p>
  );
}

export default memo(Child);

From what I understand wrapping a component in React.memo() will ensure that it only gets re-rendered whenever its props changes.

So unless whatever props that is passed onto "Parent" changes, that component, and its entire lineage of children will not get re-rendered.

However, what about its two children? Understandably if "props.fooobar" changes, they both will get re-rendered. But what if "props.somethingElse" gets changed? Which of them will get re-rendered here?

Upvotes: 2

Views: 1442

Answers (1)

Tholle
Tholle

Reputation: 112777

If another prop than fooobar given to the Parent component changes, the Parent component will be re-rendered, but the first Child component will also be re-rendered since that is given all of the props given to the parent, so its props will also change.

Example

const { memo, Fragment } = React;

const Parent = memo(props => {
  console.log("Rendered Parent");
  return (
    <Fragment>
      <Child {...props} />
      <Child foobar={props.foobar} />
    </Fragment>
  );
});

const Child = memo(({ foobar }) => {
  console.log("Rendered Child");
  return <p>{foobar}</p>;
});

class App extends React.Component {
  state = {
    foobar: "foo",
    bazqux: "baz"
  };

  componentDidMount() {
    setTimeout(() => this.setState({ foobar: "bar" }), 1000)
    setTimeout(() => this.setState({ bazqux: "qux" }), 2000)
  }

  render() {
    const { foobar, bazqux } = this.state;

    return <Parent foobar={foobar} bazqux={bazqux} />;
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<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="root"></div>

Upvotes: 1

Related Questions