本文由云+社区发表做者:前端林子html
能够结合下图来看:前端
(1) componentWillMount() 仅在render()方法前被调用一次,若是在该方法中调用了setState方法去改变组件的状态值,那么调用render()后,将会直接看到改变过了的状态值,而且不论状态值怎么改变,componentWillMount()都不会再被调用。react
(2) componentDidMount() 仅在render()方法后被当即调用一次(客户端),相对于父组件而言,该方法在子组件中会先被调用。若是须要使用一些JaveScript框架或者相似于setInterval()这样的方法,建议在该方法内使用。ajax
(3) ShouldComponentUpdate(object nextProps, object nextState) 在初始渲染调用render()方法时不会被调用,后面在接受到新的state或者props时,在render()方法前被调用。为防止一些潜在的bug,该方法默认老是返回true。若是你肯定state及props改变后不须要渲染组件,那么也能够指定返回false,须要注意的是,这样的结果会致使后面的render()、componentWillUpdate()、componentDidUpdate()都不会被调用。算法
通常的,咱们能够经过该函数来优化性能:数组
一个React项目须要更新一个小组件时,极可能须要父组件更新本身的状态。而一个父组件的从新更新会形成它旗下全部的子组件从新执行render()方法,造成新的虚拟DOM,再用diff算法对新旧虚拟DOM进行结构和属性的比较,决定组件是否须要从新渲染浏览器
无疑这样的操做会形成不少的性能浪费,因此咱们开发者能够根据项目的业务逻辑,在shouldComponentUpdate()中加入条件判断,从而优化性能babel
例如React中的就提供了一个PureComponent的类,当咱们的组件继承于它时,组件更新时就会默认先比较新旧属性和状态,从而决定组件是否更新。值得注意的是,PureComponent进行的是浅比较,因此组件状态或属性改变时,都须要返回一个新的对象或数组app
(4) componentWillReceiveProps(object nextProps) 在初始渲染调用render()方法时不会被调用,当接收到一个新的props时,该方法被调用。咱们都知道,若是改变一个状态的值,则会触发render()方法,因此能够在这个方法里调用setState()方法去改变一个状态的值,当该方法接收到新的props时,setState()就能够避免一次额外的render()了。 在这个方法里,尤为须要注意一点,就是接收到新的props必定会触发render()方法,可是render()方法被触发不必定是由于接收到了新的props框架
(5) componentWillUpdate(object nextProps, object nextState) 在初始渲染调用render()方法时不会被调用,当接收到新的props及state时,在render()方法以前被调用。
不要在此方法再去更新props 或者 state
(6) componentDidUpdate(object prevProps, object prevState) 在初始渲染调用render()方法时不会被调用,当组件更新被刷新到DOM以后被当即调用。
能够在这里访问,并修改 DOM
(7) componentWillUnmount() 在组件从DOM上卸载前被调用,在这个方法里面,咱们主要是完成一些清除操做,好比说清除掉一些过期了的定时器等。
(1) getDefaultProps(),调用1次
(2) getInitialState(),调用1次
(3) componentWillMount(),调用1次
(4) render(),调用>=1次
(5) componentDidMount():仅客户端,调用1次
(6) componentWillReceiveProps(object nextProps),调用>=0次
(7) ShouldComponentUpdate(object nextProps, object nextState),调用>=0次
(8) componentWillUpdate(object nextProps, object nextState),调用>=0次
(9) render(),调用>=1次
(10) componentDidUpdate(object prevProps, object prevState),调用>=0次
(11) componentWillUnmount(),调用1次
我写了一个小demo可直接在浏览器里运行,你们能够经过控制台查看父组件、子组件中的各生命周期调用的顺序:
<!DOCTYPE html> <html> <head> <script src="https://fb.me/react-15.2.0.js"></script> <script src="https://fb.me/react-dom-15.2.0.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script> </head> <body> <div id="app-container"></div> <script type="text/babel"> var SubCounter = React.createClass({ componentWillReceiveProps:function() { console.log('九、子组件将要接收到新属性'); }, shouldComponentUpdate:function(newProps, newState) { console.log('十、子组件是否须要更新'); if (newProps.number < 5) return true; return false }, componentWillUpdate:function() { console.log('十一、子组件将要更新'); }, componentDidUpdate:function() { console.log('1三、子组件更新完成'); }, componentWillUnmount:function() { console.log('1四、子组件将卸载'); }, render:function() { console.log('十二、子组件挂载中'); return ( <p>{this.props.number}</p> ) } }); var Counter = React.createClass({ getInitialState:function(){ return( this.state={ number:0 } ) }, componentWillMount:function(){ console.log('三、父组件挂载以前'); }, componentDidMount:function(){ console.log('五、父组件挂载完成'); }, shouldComponentUpdate:function(newProps, newState) { console.log('六、父组件是否须要更新'); if (newState.number<15) return true; return false }, componentWillUpdate:function() { console.log('七、父组件将要更新'); }, componentDidUpdate:function() { console.log('八、父组件更新完成'); }, handleClick : function(){ this.setState({ number: this.state.number + 1 }) }, render:function() { console.log('四、render(父组件挂载)'); return ( <div> <p>{this.state.number}</p> <button onClick={this.handleClick}>+</button> {this.state.number<10?<SubCounter number={this.state.number}/>:null} </div> ) } }); ReactDOM.render(<Counter />, document.getElementById('app-container')); </script> </body> </html>
点击一次按钮,经过控制台能够看到:
本文主要是图文结合地介绍了react的生命周期及执行顺序,同时附上了一个实例,能够清楚地看到父组件、子组件的调用顺序。如存在问题,欢迎指正~~~
此文已由腾讯云+社区在各渠道发布
获取更多新鲜技术干货,能够关注咱们腾讯云技术社区-云加社区官方号及知乎机构号