React生命周期主要经历四个阶段:创建阶段,实例化阶段,和更新阶段。
创建阶段
主要发生在创建组件类时,即调用React.createClass
时触发。
该阶段只会触发一个getDefaultProps
方法,该方法返回一个对象并缓存起来。然后与父组件指定的props
对象合并,最后赋值给this.props
作为该组件的默认值。
props
属性特征:
它只是一个对象,是组件用来接受外面传来的参数的;
组件内部是不允许修改props
属性的,只能通过父组件来修改。
实例化阶段
主要发生在实例化组件类的时候,也就是该组件类被调用的时候触发。该阶段触发的一系列流程执行顺序如下:
1.getInitialState
:初始化state
值。返回值赋值给组件的this.state
。
- 在
getInitialState
中可以访问组件的props
。 - 每个组件都有自己的
state
,它与props
的区别在于state
只存在组件的内部,props
在所有实例中共享。、 -
getInitialState
与getDefaultProps
的调用是有区别的。getDefaultProps
是对于组件类来说只调用一次,而getInitialState
是对于每个组件实例来讲都会调用,且只调用一次。
2.componentWillMount
:根据业务逻辑对state
进行相应的操作。也就是在render
方法调用之前,修改state
的最后一次机会。
3.render
:根据state
的值,生成页面需要的虚拟DOM
结构,并返回该结构。生命周期唯一一个必须的方法。该方法满足以下条件:
- 只能通过
this.props
和this.state
访问数据。(不能修改) - 可以返回
null
,false
或者任何React组件。 - 只能出现一个顶级组件,不能返回一组元素。
- 不能修改组件的状态。
- 不能修改
DOM
的输出。
4.componentDidMount
:对根据虚拟DOM
而生的真实DOM
进行相应的处理。组件内部可以通过ReactDOM.findDOMNode(this)
来获取当前组件的结点,然后可以像Web开发中操作DOM
了。
该方法不会在服务端被渲染的过程中调用。
可以在该方法中执行
setTimeout
,setInterval
或发送Ajax
请求等。
更新阶段
主要发生在用户操作之后或父组件有更新时,会出发一系列的流程,执行顺序如下:
1.componentWillReceiveProps
:有一个参数nextProps
。当组件接收到新的props
时,会触发该函数。在该函数中,可以通过调用setState
更新state
(接收到新的props
会触发一次render
,调用this.setState
也会触发一次render
,但在componentWillReceiveProps
中调用this.setState
,React会把原本需要的两次render
合并成一次)。也可以通过判断nextProps
值,做出相应的操作。
2.shouldComponentUpdate
:返回一个布尔值。在组件接收到新的props
或state
时被执行,可以根据事先定好的判断逻辑,做出最后要不要更新组件的决定。返回false
时,则不会执行render
以及后面的componentWillUpdate
,componentDidUpdate
方法。默认返回true
。
可以运用这个函数来提升应用速度。
3.componentWillUpdate
:接受两个参数:object nextProps
,object nextState
。在组件接收到新的props
或state
,但还没有render
时被执行。
当上边的方法返回true
时,就可以在该方法中做一些更新前的操作。
不建议在该方法中再去个更新props
或state
。
4.render
:根据一系列的diff
算法,生成需要的虚拟DOM
数据。
5.componentDidUpdate
:接受两个参数:object prevProps
和object prevState
。与componentDidMount
类似,在组件被重新渲染之后被调用。可以在这里访问并修改DOM
。
销毁阶段
只会触发一个componentWillUnmount
方法。
每当React组件使用完一个组件时,该组件必须从DOM
中卸载后被销毁,此时componentWillUnmount
会被执行,完成所有的清理和销毁工作,在 componentDidMount
中添加的任务都需要在该方法中撤销,如创建的定时器或时间监听器。