Как проверить, какие реквизиты были изменены в компоненте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