概述
React組件的生命週期就是React組件從建立到消亡的過程。大致分為三個階段:
1.Mounting 組件裝載和初始化2.Updating 組件更新 3.Unmounting 組件卸載
圖例
生命週期函數及其用法
constructor(props, context){...}
此函數對應圖中getInitialState方法,由於React在ES6的實現中去掉了getInitialState這個hook函數,規定state在constructor中實現。該函數為組件的建構函式,用於初始化組件狀態(state),在組件建立的時候調用一次,在組件的整個生命週期只調用一次。方法中不可以使用setState方法
componentWillMount(){...}
在組件裝載(render)之前調用一次。在這個函數裡面調用setState,本次的render函數可以看到更新後的state,並且該方法在組件生命週期只調用一次。在本方法中可以使用fetch非同步請求載入操作。
componentDidMount(){...}
組件裝載(render)完成後調用一次,此時子組件也已經裝載完成,可以在該方法中使用refs。也可以使用setState方法,該方法在組件生命週期中只調用一次。
componentWillReceiveProps(nextProps){...}
props是通過父組件傳遞給子組件的。當父組件發生render的時候子組件就會調用componentWillReceiveProps(不管props有沒有更新,也不管父子組件之間有沒有資料交換)。此方法用於更新群組件資料。方法中可以使用setState,並且在組件的生命週期中可能被調用多次。
bool shouldComponentUpdate(nextProps, nextState){...}
注意本方法是唯一一個包含傳回值的生命週期函數,其他函數傳回值都為void。組件裝載之後,每次調用setState後都會調用shouldComponentUpdate判斷是否需要重新渲染組件。預設返回true,需要重新render。在比較複雜的應用裡,有一些資料的改變並不影響介面展示,可以在這裡做判斷,最佳化渲染效率。方法內不可以使用setState函數。
componentWillUpdate(nextProps, nextState){...}
shouldComponentUpdate返回true或者調用forceUpdate之後,componentWillUpdate會被調用。需要特別注意的是,在這個函數裡面,你就不能使用 this.setState 來修改狀態。這個函數調用之後,就會把 nextProps 和 nextState 分別設定到 this.props 和 this.state 中。緊接著這個函數,就會調用 render() 來更新介面了。
render(){...}
render即為組件渲染函數,render中不能使用setState
componentDidUpdate(prevProps,prevState){...}
除了首次render之後調用componentDidMount,其它render結束之後都是調用componentDidUpdate。函數內不可使用setState 方法。
componentWillUnmount(){...}
組件即將卸載時調用。一般在componentDidMount註冊的監聽事件需要在該方法中登出刪除,以免不必要的錯誤。 執行個體
/** * 生命週期函數樣本. * */import React from 'react';/** * 父組件 */export default class LifeCircle extends React.Component{ constructor(props){ super(props); this.state=({ propsToChild:1 }) } addCount=()=>{ this.setState({ propsToChild:this.state.propsToChild+1 }) } render(){ return ( <div> <button onClick={this.addCount}>累加計數值</button> <LifeCircleChild currentCount={this.state.propsToChild}></LifeCircleChild> </div> ) }}/** * 生命週期組件 */class LifeCircleChild extends React.Component{ /** * 建構函式,初始化state. * @param props * @return void */ constructor(props){ super(props); this.state=({ currentCount:props.currentCount,//計數,來自父組件 width:0,//當前文檔body寬度 height:0,//當前文檔body高度 }) } /** * 組件render前執行的函數,在此函數中可以執行一些非同步請求並setState. * @return void */ componentWillMount(){ //非同步請求,傳回值內容為 {currentCountResult:1} fetch('/currentCount.json') .then((res)=> res.json()) .then((json)=>{ this.setState({ currentCount:json.currentCountResult }) }); } /** * 組件render之後執行,通常在此方法中註冊一些監聽事件. * @return void */ componentDidMount(){ //添加瀏覽器視窗resize監聽事件,通知this.onWindowResize方法. window.addEventListener('resize', this.onWindowResize); } /** * 當父組件render後調用,根據父組件的值重新渲染組件狀態(state). * @param Object nextProps [父組件傳來的參數對象] * @return void */ componentWillReceiveProps(nextProps){ this.setState({ currentCount:nextProps.currentCount }) } /** * 判斷是否需要重新渲染組件,true為渲染,本方法中當計數能被3整除時,不渲染組件. * @param Object nextProps [將要渲染的props] * @param Object nextState [將要渲染的狀態] * @return boolean [是否渲染] */ shouldComponentUpdate(nextProps, nextState){ if(nextState.currentCount%3===0){ return false; } return true; } /** * shouldComponentUpdate返回true或者調用forceUpdate之後,componentWillUpdate會被調用. * @param Object nextProps [this.props = nextProps] * @param Object nextState [this.state = nextState] * @return void */ componentWillUpdate(nextProps, nextState){ console.log(nextProps); console.log(nextState); } /** * 除了首次render之後調用componentDidMount,其它render結束之後都是調用componentDidUpdate。函數內不可使用setState 方法. * @param Object prevProps * @param Object prevState * @return void */ componentDidUpdate(prevProps,prevState){ console.log(prevProps); console.log(prevState); } /** * 組件即將卸載時調用。一般在componentDidMount註冊的監聽事件需要在該方法中登出刪除,以免不必要的錯誤. * @return void */ componentWillUnmount(){ //在組件即將銷毀的時候取消resize的監聽 window.removeEventListener('resize', this.onWindowResize); } /** * 當瀏覽器視窗大小發生變化時,獲得文檔body的寬度和高度. * @return void */ onWindowResize=()=>{ let width = document.body.offsetWidth; let height = document.body.offsetHeight; this.setState({ width:width, height:height }) }; /** * 渲染虛擬dom * @return void */ render(){ return ( <div> <p> 當前計數:{this.state.currentCount} </p> <p> 當前文檔body高度:{this.state.height} </p> <p> 當前文檔body寬度:{this.state.width} </p> </div> ) }}