总览
2019/03/17更新:本文内容相对过时,React16之后的生命周期有所更新,原有的部分生命周期方法被抛弃,几个新的生命周期方法被引入,具体内容请参照官网。
了解组件的生命周期是深入理解React的基础之一,这样我们能在合适的组件生命阶段做合适的逻辑处理。
一般来说,前缀加了will都是在组件渲染之前调用,加了did都是在组件渲染之后调用。React声明周期的方法都很顾名思义,便于记忆。
挂载 | 更新状态 | 更新属性 | 卸载 |
---|---|---|---|
componentWillReceiveProps() | |||
constructor() | shouldComponentUpdate() | shouldComponentUpdate() | componentWillUnmount() |
componentWillMount() | componentWillUpdate() | componentWillUpdate() | |
render() | render() | render() | |
componentDidMount() | componentDidUpdate() | componentDidUpdate() |
参考3中给出了一个用于验证声明周期的示例。
主要方法介绍
对于有状态组件,笔者个人倾向于使用ES6的class关键字,虽然class关键字只是一个语法糖,JavaScript依然是基于原型链的面向对象,但使用class关键字有助于限制面向对象的实现方式,从而使代码得到统一,当然作为一个JavaScript学习者,在使用class关键字的同时也需要熟悉底层实现。
constructor()方法就是这种方式创建组件的构造方法(对应使用React.createClass方式的方法是getInitialState(),需要使用这种方式的读者请查阅其他资料),constructor()中一般主要有三个任务:第一调用super()方法;第二为成员方法绑定this;第三完成组件状态的初始化。
componentWillMount()紧挨着发生在render()方法调用之前,注意尽量不要在这里引入一些带有副作用的操作,在这个方法里调用setState()是不会触发一个新的render()方法的。
componentDidMount()紧接着render()方法之后调用,这里是一个很合适加载数据的地方,这里更新状态也会触发重新渲染。
componentWillReceiveProps(nextProps),当一个组件需要更新属性时,触发的第一个方法就是componentWillReceiveProps()方法。该方法接收了一个nextProps的参数,该参数是待更新的属性。注意此时组件还没有被更新,当前属性仍然是this.props,更新后的属性才是nextProps。注意由于父组件引起当前组件的重新渲染时,有的时候属性没有被改变的情况下该方法也会被React调用,此外该方法不会在调用setState()方法的时候被触发。
shouldComponentUpdate(nextProps, nextState),该方法接收了两个参数,nextProps和nextState分别表示待更新的属性和状态。顾名思义,该方法就是告诉React,在属性和状态发生了当前这样的改变的情况下组件是否需要更新。如果需要则返回true,否则返回false。如果返回false,那后续的componentWillUpdate(),render(),和componentDidUpdate()方法都不会被调用。
componentWillUpdate(nextProps, nextState),依然接收待更新的属性和状态做为参数。这里不能调用setState()。
componentDidUpdate(prevProps, prevState),该方法发生在组件更新之后,接收的两个参数分别是更新前的属性和更新前的状态,更新后的属性和状态可以通过this访问。这里组件已经完成渲染更新,已经可以操作更新后的DOM节点了。
render(),渲染方法,React会一句render的返回结果计算虚拟DOM并进一步更新真实DOM。
componentWillUnmount(),在组件卸载和毁灭之前被触发,这里可以完成一些清理工作(数据,DOM之类的)。
forceUpdate()方法
这里有必要强调一下forceUpdate()方法几个关键点。forceUpdate()方法会会绕过当前组件以及子组件的shouldComponentUpdate()方法,直接进入更新阶段(componentWillUpdate(),render(),和componentDidUpdate()方法)。官方建议一般情况下尽量不用使用这个方法。
无状态函数式组件
注意无状态函数式组件不存在生命周期函数。