生命周期:componentWillReceiveProps在componentDidMount之前调用

时间:2016-05-24 10:16:10

标签: reactjs

如果我理解正确,组件的React生命周期应确保在componentDidMount之前调用componentWillReceiveProps。当我在组件的初始安装上测试它时,它似乎以这种方式工作。但是当组件之前已经安装并重新安装时,顺序就是另一种方式。这是预期的行为吗?以下代码说明了可能以这种方式引入的潜在错误:

class Example extends React.Component {
    componentDidMount() { 
        this.something = { foo: 'bar' };
    }
    componentWillReceiveProps(nextProps) {
        this.something.foo;
        // Throws a TypeError if this code is reached before
        // componentDidMount is called.
    }
}

1 个答案:

答案 0 :(得分:14)

简短回答
确实无法保证解雇这些方法的顺序。这就是为什么(如你的例子中)使用props和state之外的组件变量的原因之一并不是一个好主意。

更好:如果您需要在生命周期事件之外使用它,请将{ foo: 'bar' }置于状态。

答案越长

componentDidMount()仅在每个生命周期中调用一次:

    第一次渲染后
  • (注意:所有孩子都渲染完毕,所有孩子也称他们为componentDidMount后)
  • 如果组件在卸载后呈现(但这确实是一个新的生命周期)

componentWillReceiveProps()在生命周期中的第一次渲染时不会被调用,但是当父级再次发送道具时,会在所有后续渲染时调用它。

通常情况下,第二个渲染(触发)componentWillReceiveProps将在组件(及其子组件)完成安装之后出现,因此在componentDidMount()之后。

但我可以想到至少有一个(可能是理论上的)情况,订单会逆转:

  1. 组件接收道具,并开始渲染。
  2. 当组件呈现时, 但尚未完成呈现 ,组件会收到新的道具。
  3. componentWillReceiveProps()被解雇,(但componentDidMount尚未解雇)
  4. 在所有子项和组件本身完成渲染后,componentDidMount()将会触发。
  5. 所以componentDidMount()不是初始化组件变量的好地方,例如{ foo: 'bar' } componentWillMount()将是一个更好的生命周期事件 但是,我不鼓励在反应组件中使用组件范围的变量,并坚持设计原则:

    • 所有组件变量都应该处于state或props(并且是不可变的)
    • 所有其他变量都受生命周期方法的约束(而不是超出该范围)