React組件的生命週期有一堆的相關函數,其實就是一推的鉤子函數。在React組件建立的各個階段觸發特定的鉤子函數。react
能夠先大概看一下下面這張圖:安全
constructor
構造函數,在建立組件的時候調用一次。服務器
constructor(props, context)
componentWillMount
在組件掛載以前調用一次。若是在這個函數裏面調用setState,render()知道state發生變化,而且只渲染一次。網絡
void componentWillMount()
render
render是一個React組件所必不可少的核心函數。不要在render裏面修改state。也不要去讀寫DOM或者與服務器交互,保持render()方法的純淨。app
ReactElement render()
componentDidMount
在組件掛載以後調用一次。這個時候,子組件也都掛載好了,能夠在這裏使用refs。dom
void componentDidMount()
shouldComponentUpdate
這個方法在初始化render時不會執行,當props或者state發生變化時執行。函數默認返回true,須要從新render。返回false,就不會從新render了。componentWillUpdate和componentDidUpdate方法也不會被調用。在比較複雜的應用裏,有一些數據的改變並不影響界面展現,能夠在這裏作判斷,優化渲染效率。函數
boolean shouldComponentUpdate( object nextProps, object nextState )
componentWillUpdate
shouldComponentUpdate返回true以後,componentWillUpdate會被調用。須要特別注意的是,在這個函數裏面,不要用this.setState來修改狀態。否則這個函數會無限循環執行。這個函數調用以後,就會把nextProps和nextState分別設置到this.props和this.state中。緊接着這個函數,就會調用render()來更新界面了。測試
void componentWillUpdate( object nextProps, object nextState )
componentDidUpdate
除了首次render以後調用componentDidMount,其它render結束以後都是調用componentDidUpdate。優化
void componentDidUpdate()
componentWillReceiveProps
props是父組件傳遞給子組件的。父組件發生render的時候子組件就會調用componentWillReceiveProps(無論props有沒有更新,也無論父子組件之間有沒有數據交換)。在這個回調函數裏面,你能夠根據屬性的變化,經過調用this.setState()來更新你的組件狀態,舊的屬性仍是能夠經過this.props來獲取,這裏調用更新狀態是安全的,並不會觸發額外的render調用。ui
void componentWillReceiveProps(nextProps) { this.setState({...}); }
componentWillUnmount
當組件要被從界面上移除的時候,就會調用componentWillUnmount(),在這個函數中,能夠作一些組件相關的清理工做,例如取消計時器、網絡請求等。
void componentWillUnmount()
var React = require('react'); var ReactDOM = require('react-dom'); class Parent extends React.Component { constructor(){ super() console.log("%cparent -- constructor","color:green"); this.state = { name : 'Lucy' } } componentWillMount(){ console.log("%cparent -- componentWillMount","color:green"); } componentDidMount(){ console.log("%cparent -- componentDidMount","color:green"); } componentWillReceiveProps(){ console.log("%cparent -- componentWillReceiveProps","color:green"); } shouldComponentUpdate(){ console.log("%cparent -- shouldComponentUpdate","color:green"); return true; } componentWillUpdate(){ console.log("%cparent -- componentWillUpdate","color:green"); } componentDidUpdate(){ console.log("%cparent -- componentDidUpdate","color:green"); } componentWillUnmount(){ console.log("%cparent -- componentWillUnmount","color:green"); } changeName(){ this.setState({name : 'Jone'}) } unmountComponent(){ ReactDOM.unmountComponentAtNode(document.getElementById("app")); } render(){ console.log("%cparent -- render","color:green"); return( <div style={{border:'1px solid #000',color:'green'}}> <h2>Parent:</h2> <h3>hello {this.state.name}</h3> <button onClick={this.changeName.bind(this)}>state改變</button> <button onClick={this.unmountComponent.bind(this)}>卸載組件</button> <Child props1="haha"></Child> </div> ) } } class Child extends React.Component { constructor(){ super() console.log(" %cchild -- constructor","color:blue"); this.state = { } } componentWillMount(){ console.log(" %cchild -- componentWillMount","color:blue"); } componentDidMount(){ console.log(" %cchild -- componentDidMount","color:blue"); } componentWillReceiveProps(){ console.log(" %cchild -- componentWillReceiveProps","color:blue"); } shouldComponentUpdate(){ console.log(" %cchild -- shouldComponentUpdate","color:blue"); return true; } componentWillUpdate(){ console.log(" %cchild -- componentWillUpdate","color:blue"); } componentDidUpdate(){ console.log(" %cchild -- componentDidUpdate","color:blue"); } componentWillUnmount(){ console.log(" %cchild -- componentWillUnmount","color:blue"); } changeName(){ this.setState({name : 'Jone'}) } render(){ console.log(" %cchild -- render","color:blue"); return( <div style={{border:'1px solid #000',margin:'10px',color:'blue'}}> <h2>Child:</h2> </div> ) } } ReactDOM.render( <Parent></Parent>, document.getElementById('app') );
改變父組件的state:
卸載組件後: