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中添加的任务都需要在该方法中撤销,如创建的定时器或时间监听器。