Поведение React.memo

#javascript #reactjs

#javascript #reactjs

Вопрос:

Рассмотрим следующие простые компоненты:

 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);

 

Насколько я понимаю, перенос компонента в React.memo() гарантирует, что он будет повторно отображаться только при изменении его реквизитов.

Таким образом, если какие-либо реквизиты, которые передаются «родительским» изменениям, этот компонент и вся его дочерняя линия не будут повторно отображаться.

Однако, как насчет двух его дочерних элементов? Понятно, что если «props.fooobar» изменится, они оба будут повторно отображены. Но что, если «props.somethingElse» будет изменен? Какие из них будут повторно отображены здесь?

Комментарии:

1. Он не будет повторно отображаться с метода визуализации функции, в вашем случае возврат не будет повторно отображен.

Ответ №1:

Если изменяется другой реквизит, чем fooobar заданный Parent компоненту, Parent компонент будет повторно отображен, но первый Child компонент также будет повторно отображен, поскольку ему заданы все реквизиты, предоставленные родительскому элементу, поэтому его реквизиты также изменятся.

Пример

 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>