Как проверить, какие реквизиты были изменены в компонентеWillReceiveProps

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

т.е.

componentWillReceiveProps (newProps) {
  if( /* newProps.profileImage is different to previous props */ ) /* do stuff */
}

Ответ 1

Обратите внимание, что функция componenWillReceiveProps будет устаревать в будущем. Цитирование официальной документации:

Если вы использовали componentWillReceiveProps для повторного вычисления некоторых данных только при изменении пропеллера, вместо этого используйте помощник memoization.

Это относится к случаю, когда ваша проверка внутри componentWillReceiveProps заключалась в том, чтобы избежать излишнего повторного вычисления одной и той же вещи много раз. В связанном сообщении в блоге он предлагает кэшировать результат дорогостоящей функции, чтобы ее можно было искать, а не пересчитывать. Это можно сделать с помощью помощника, такого как memoize-one.

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

Опять же, связанное сообщение в блоге описывает это более подробно, но в двух словах:

  • Компонент "полностью контролируемый" относится к функциональному компоненту без состояния (родительский компонент отвечает за обработку состояния).
  • "Полностью неконтролируемая" альтернатива - это та, которая использует props для установки начального состояния, а затем игнорирует все дальнейшие изменения в реквизитах.

В очень редких случаях вы можете использовать жизненный цикл getDerivedStateFromProps в качестве последнего средства.

Эта функция получает (props, state) и возвращает любые изменения состояния перед render, предоставляя вам элемент управления, чтобы делать все, что вы хотите.


Оригинальный ответ, для более старых версий React

В тот момент, когда этот метод жизненного цикла вызывается, this.props ссылается на предыдущий набор реквизитов.

Чтобы сравнить одно свойство foo на новых реквизитах с тем же свойством на старых, вы можете просто сравнить newProps.foo с this.props.foo. Итак, в вашем примере:

componentWillReceiveProps (newProps) {
  if( newProps.profileImage !== this.props.profileImage ) /* do stuff */
}

Ответ 2

Поскольку React 16.3, componentWillReceiveProps не рекомендуется использовать, обратитесь к документации unsafe_componentwillreceiveprops на веб-сайте реагирования.

getDerivedStateFromProps этого используйте getDerivedStateFromProps:

static getDerivedStateFromProps(nextProps, prevState) {
  if(nextProps.profileImage !== prevState.profileImage ) {
    return {stateFoo: 'valueBar'};
  }
}

Возвращаемое значение ведет себя аналогично setState.

Ответ 3

Вы все еще можете сравнить с this.props.profileImage, потому что он не обновляется до тех пор, пока не вызывается componentWilReceiveProps. Например, в документах используется этот пример:

componentWillReceiveProps: function(nextProps) {
  this.setState({
    likesIncreasing: nextProps.likeCount > this.props.likeCount
  });
}

Ответ 4

Вы также можете пройти через все реквизиты, чтобы увидеть, что изменилось.

componentWillReceiveProps(nextProps) {
  for (const index in nextProps) {
    if (nextProps[index] !== this.props[index]) {
      console.log(index, this.props[index], '-->', nextProps[index]);
    }
  }
}

Ответ 5

Да, вы можете проверить, изменилась ли определенная опора. this.props относится к реквизитам, прежде чем они изменились. Так, например:

componentWillReceiveProps(newProps) {
  if( newProps.profileImage != this.props.profileImage ) {
    /* do stuff */
  }
}

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

Ответ 6

Точно так же, как примечание всем, кто находит это в будущем. Похоже, что componentWillReceiveProps() будет устаревшим. В Docs теперь предлагается использовать getDerivedStateFromProps(). Объяснения относительно того, почему можно найти здесь: https://reactjs.org/blog/2018/03/29/react-v-16-3.html#component-lifecycle-changes