如何检查componentWillReceiveProps

时间:2016-07-29 09:03:56

标签: reactjs

有没有办法在componentWillReceiveProps内检查哪些道具改变了(不在其他地方存放旧道具)?

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

7 个答案:

答案 0 :(得分:35)

请注意,将来函数componenWillReceiveProps将被弃用。引用the official documentation

  

如果您使用componentWillReceiveProps仅重新计算某些数据   当一个道具改变时,改为使用一个memoization帮助器。

这指的是componentWillReceiveProps内的检查是为了避免多次不必要地重新计算同一件事。在linked blog post中,它建议缓存昂贵函数的结果,以便可以查找它,而不是重新计算。这可以使用诸如memoize-one之类的帮助程序来完成。

  

如果你使用componentWillReceiveProps来“重置”一些状态   道具改变,考虑使组件完全受控制或   用钥匙完全不受控制。

同样,linked blog post更详细地描述了这一点,但简而言之:

  • “完全控制”组件是指没有状态的功能组件(父组件负责处理状态)。
  • “完全不受控制”的替代方案是使用props设置初始状态,然后忽略对道具的所有进一步更改。
  

在极少数情况下,您可能想要使用getDerivedStateFromProps   生命周期作为最后的手段。

此函数接收(props, state)并在调用render之前返回对状态的任何更改,让您可以控制执行任何操作。

原始答案,适用于旧版本的React

在调用此lifecycle method的时间点,this.props指的是上一组道具。

要将新道具上的单个属性foo与旧道具上的相同属性进行比较,您只需将newProps.foothis.props.foo进行比较即可。所以在你的例子中:

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

答案 1 :(得分:9)

您还可以遍历所有道具以查看更改内容。

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

答案 2 :(得分:9)

自React 16.3起,不建议使用componentWillReceiveProps,请参阅react网站上的unsafe_componentwillreceiveprops文档。

改为使用getDerivedStateFromProps

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

返回值的行为与setState类似。

答案 3 :(得分:3)

您仍然可以与this.props.profileImage进行比较,因为在调用componentWilReceiveProps之前它不会更新。例如,在docs中,使用了此示例:

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

答案 4 :(得分:0)

是的,您可以检查特定道具是否已更改。 this.props指的是之前的道具。例如:

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

注意:每次调用方法时道具都不一定会改变,所以值得测试看看哪个道具发生了变化。

答案 5 :(得分:0)

就像将来发现这一点的人一样。看来componentWillReceiveProps()将被弃用。文档现在建议您使用getDerivedStateFromProps()。关于为什么可以在这里找到解释:https://reactjs.org/blog/2018/03/29/react-v-16-3.html#component-lifecycle-changes

答案 6 :(得分:0)

你应该实现这样的逻辑:

import React from 'react';
import { View, Dimensions } from 'react-native';
class DataTable extends React.Component {
  state = {
      previousProps: null // Keep snapshot of current props in State & never change this through setState()
  }

  static getDerivedStateFromProps(props, currentState) {
      if (JSON.stringify(props) === JSON.stringify(currentState.previousProps)){
          //Here it's mean that props are not changed!!!
          return null;
      }

      //Here it's mean props are changed!
      //Here You find out what are changed through looping
      //Don't forget to return new props as a state here!
      return {
          previousProps: props,
          //...Pass your new state depending on new props here!
      }

  }


  render() {
      return(
          <View>
               {...}
          </View>
      )
  }
}