Как дочерний компонент получает реквизиты от родительского компонента, не прослушивая метод жизненного цикла?

Для обновления объекта props в дочерних компонентах обычно используется метод жизненного цикла ComponentWillReceiveProps. Но я понял, что props для дочернего компонента можно обновить, не прослушивая ComponentWillReceiveProps.

Например, в следующем компоненте с именем App дочерний компонент Comp может получить props без прослушивания метода жизненного цикла ComponentWillReceiveProps.

Основной компонент App:

import React from 'react';
import ReactDOM from 'react-dom';
import {Comp} from "./comp";

class App extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      counter: 0
    }

    this.incrementCounter = this.incrementCounter.bind(this);
  }

  componentDidMount() {
    this.setState({
      counter: 100
    })
  }

  incrementCounter() {
    this.setState({
      counter: this.state.counter + 1
    })
  }

  render() {
    return (
      <div>
              <button onClick={this.incrementCounter}>Increment</button>
              <br />
              <br />
              <Comp counter={this.state.counter}/>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('container'));

и дочерний компонент Comp:

import React from 'react';

export class Comp extends React.Component {

  constructor(props) {
    super(props);
    this.state = {}
  }

  componentDidUpdate(prevProps, prevState) {
    console.log("prev props ", prevProps);
    console.log("prev state", prevState)
  }

  render() {
    return <span>Props received: {JSON.stringify(this.props)}</span>
  }
}

Вот также рабочая демонстрация приведенного выше кода, который я подготовил

Редактировать jovial-engelbart-3dsun

Вы увидите, что дочерний компонент Comp получает свойство counter без прослушивания какого-либо метода жизненного цикла.

Что это значит? Я что-то упустил?


person Amanda    schedule 09.07.2019    source источник
comment
Я думаю, что дочерний компонент повторно отображается. Вот почему вы получаете обновленный реквизит. При изменении состояния приложения оно снова отображается, что также приводит к повторному отображению дочернего компонента. Метод жизненного цикла удобен, когда родительский компонент не подлежит повторному рендерингу. Мы просто хотим, чтобы наш дочерний компонент повторно отображался.   -  person Osama Khalid    schedule 09.07.2019
comment
@OsamaKhalid Я не понимаю. Не могли бы вы привести пример случая, когда родительский компонент не перерисовывается, а дочерний компонент перерисовывается.   -  person Amanda    schedule 09.07.2019
comment
Извините, я ошибся в комментарии выше. ComponentWillReceiveprops не управляет повторным рендерингом дочернего компонента. Дочерний компонент всегда будет перерисовываться при изменении состояния родительского компонента. Использование этого метода заключается в том, что он дает нам возможность принимать логические решения для нашего дочернего компонента, поскольку у него есть предыдущие реквизиты и следующие реквизиты, поэтому мы можем использовать их для установки некоторых данных/состояния для нашего дочернего компонента до вызова рендеринга дочерней функции. .   -  person Osama Khalid    schedule 09.07.2019


Ответы (2)


componentWillReceiveProps() — это устаревший метод жизненного цикла, который срабатывает, когда компонент собирается получить новые реквизиты. Однако он не может контролировать, действительно ли компонент получает эти реквизиты.

https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops

Компонент будет получать обновленные реквизиты от родителя независимо от того, выполняется ли componentWillReceiveProps().

import React from 'react';

export class Comp extends React.Component {

  constructor(props) {
    super(props);
    this.state = {}
  }

  render() {
    console.log(this.props.counter) //still gets printed with new props data
    return <span>Props received: {JSON.stringify(this.props)}</span>
  }
}

Обратите внимание, что реквизиты передаются строго от родительского к дочернему компоненту.

Когда родительский компонент повторно визуализируется посредством изменения состояния, он также повторно отображает дочерние компоненты и передает обновленные реквизиты. Теперь у дочернего компонента есть доступ к этим новым реквизитам, и они проходят жизненный цикл событий React.

Такие события, как componentDidUpdate() и componentWillReceiveProps(), позволяют вам выполнять некоторую дополнительную логику, но они не требуются для получения компонентом свойств или повторного рендеринга. Компонент будет повторно отображаться независимо от их использования.

Кроме того, дочерний компонент может обновлять себя посредством внутреннего обновления состояния так же, как и любой компонент на основе классов.

person Cool Guy    schedule 09.07.2019

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

Поведение по умолчанию заключается в повторном рендеринге при каждом изменении состояния, и в подавляющем большинстве случаев следует полагаться на поведение по умолчанию.

Если вы не хотите, чтобы ваш дочерний компонент повторно отображался при каком-либо условии, вы можете использовать жизненный цикл shouldComponentUpdate. Этот жизненный цикл — просто оптимизация производительности. Подробнее об обновлении shouldcomponentupdate

Также рассмотрите возможность использования PureComponent вместо component. Он выполняет поверхностное сравнение свойств и состояния и снижает вероятность того, что вы пропустите необходимое обновление. Подробнее о PureComponent

person Vaibhav Shukla    schedule 09.07.2019