组件在初始化时会触发一个数据初始化和3个钩子函数:
1、constructor
数据的初始化
2、componentWillMount()
仅在render()方法前被调用一次,如果在该方法中调用了setState方法去改变组件的状态值,那么调用render()后,将会直接看到改变过了的状态值,并且不论状态值怎么改变,componentWillMount()都不会再被调用。
3、 render()
react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。
4、componentDidMount()
组件渲染之后调用,可以通过this.getDOMNode()获取和操作dom节点,只调用一次。
仅在render()方法后被立即调用一次(客户端),相对于父组件而言,该方法在子组件中会先被调用。如果需要使用一些JaveScript框架或者类似于setInterval()这样的方法,建议在该方法内使用。
在更新时也会触发5个钩子函数:
5、componentWillReceiveProps(nextProps)
组件初始化时不调用,组件接受新的props时调用。
6、shouldComponentUpdate(nextProps, nextState)
react性能优化非常重要的一环。
在初始渲染调用render()方法时不会被调用,后面在接受到新的state或者props时,在render()方法前被调用。
我们可以设置在此对比前后两个props和state是否相同,如果相同则返回false阻止更新,因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,节省大量性能,尤其是在dom结构复杂的时候。
需要注意的是,这样的结果会导致后面的render()、componentWillUpdate()、componentDidUpdate()都不会被调用。不过调用this.forceUpdate会跳过此步骤。
React中的就提供了一个PureComponent的类,当我们的组件继承于它时,组件更新时就会默认先比较新旧属性和状态,从而决定组件是否更新。值得注意的是,PureComponent进行的是浅比较,所以组件状态或属性改变时,都需要返回一个新的对象或数组
7、componentWillUpdate(nextProps, nextState)
在初始渲染调用render()方法时不会被调用,当接收到新的props及state时,在render()方法之前被调用。
8、render()
react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。
9、componentDidUpdate()
在初始渲染调用render()方法时不会被调用,当组件更新被刷新到DOM之后被立即调用,此时可以获取dom节点。。
不要在此方法再去更新props 或者 state。
卸载钩子函数
10、componentWillUnmount()
在组件从DOM上卸载前被调用,在这个方法里面,我们主要是完成一些清除操作,比如说清除掉一些事件监听、过时了的定时器等。
以上可以看出来react总共有8个周期函数(render重复一次),这8个函数可以满足我们所有对组件操作的需求,利用的好可以提高开发效率和组件性能。
执行顺序及次数
(1) constructor,调用1次
(2) componentWillMount(),调用1次
(3) render(),调用>=1次
(4) componentDidMount():仅客户端,调用1次
(5) componentWillReceiveProps(object nextProps),调用>=0次
(6) ShouldComponentUpdate(object nextProps, object nextState),调用>=0次
(7) componentWillUpdate(object nextProps, object nextState),调用>=0次
(8) render(),调用>=1次
(9) componentDidUpdate(object prevProps, object prevState),调用>=0次
(10) componentWillUnmount(),调用1次