React before16.3與after 16.3的生命週期詳解以及簡單應用場景

before React 16.3


父子組件樣例:

//parent.jsx複製代碼


//child.jsx
複製代碼


React父子組件掛載階段:

parent constructor
->parent componentWillMount
->parent render
->child constructor
->child componentWillMount
->child render
->child componentDidMount
->parent componentDidMount複製代碼

React父子組件更新階段:

parent shouldComponentUpdate
//shouldComponentUpdate的返回值 若是爲true則向下執行 不然false將不會再向下執行
->parent componentWillUpdate
->parent render
->child componentWillReceiveProps
->child shouldComponentUpdate
->child componentWillUpdate
->child render
->child componentDidUpdate
->parent componentDidUpdate複製代碼

React卸載階段:

componentWillUnmount複製代碼


constructor( props ):React的構造函數通常用來初始化state和爲事件處理函數綁定實例,若是須要引入訂閱或者反作用則請使用componentDidMount。

componentWillMount( ):它在render以前被調用,但不要在這裏加入this.setState由於它並不會執行,並且不要在這個生命週期函數裏去獲取服務端數據,由於在render以前不會返回數據,因此它通常只用於服務端渲染。

componentWillReceiveProps( nextProps ): 通常用於子組件中使用,會在已掛載的父組件中接收新的props時被調用,能夠用來比較this.props和nextProps的值去使用this.setState進行state變化。 須要注意的是,若是父組件致使子組件從新渲染,即便props沒有改變,此函數也會被執行一次!在掛載過程當中,父組件初始化props不會致使子組件的此函數被調用,只有當父組件的props發生更新後調用此方法。

shouldComponentUpdate( nextProps, nextState ) : 當props或者state發生變化時,此函數會在渲染執行前被調用,默認返回值是true,可是使用該函數時必需要有一個Boolean返回值,不然瀏覽器會提示錯誤。此方法僅做爲性能優化存在,比較this.props和nextProps還有this.state和nextState的值,返回false則React能夠跳過這次更新,也不會再去調用componentWillUpdate、render、componentDidUpdate,可是此時子組件依然能夠根據state的改變從新渲染。

componentWillUpdate( nextProps, nextState ) : 當組件的props或者state發生變化時,會在渲染執行以前被調用,但shouldComponentUpdate返回false時,今生命週期函數將不會被執行。在這裏可使用this.setState,但須要進行his.props和nextProps還有this.state和nextState的值對比後再去改變state的值,不然將會形成死循環,瀏覽器內存佔滿後崩潰,建議在shouldComponentUpdate中去改變state的值。

render( ) : 當render被調用時,它會檢查this.state和this.props的變化返回 React元素、數組或者Fragments、portals、字符串或者數值類型、boolean類型或者null。

componentDidMount( ) : 會在組件裝載後當即被調用,可用來經過網絡請求獲取數據,直接使用this.setState更新state的值,也能夠添加事件訂閱,但須要在componentWillUnmount進行卸載訂閱。

componentDidUpdate( preProps,preState ) : 會在更新後當即被調用,首次渲染不會執行此方法,但shouldComponentUpdate返回false時,今生命週期函數將不會被執行。 當組件更新完之後,對比更新先後props的值,若是不相等則能夠去執行this.setState或者網絡請求,可是沒有條件比對直接去執行其餘操做將會形成死循環。

componentWillUnmount( ) : 會在組件卸載或者銷燬以前被調用。此函數用來必要的清除操做,好比clearInterval清除定時器,取消網絡請求或者清除在componentDidMount中使用的訂閱。這裏不該該使用this.setState,由於組件永遠不會從新渲染。

after React 16.3



static getDerivedStateFromProps( props, state ) : 會在render以前被調用,初次掛載或者更新後都會被調用,它應返回一個對象去更新state,返回null則不更新任何內容。這個生命週期函數也間接取代了老版本React中的componentWillReceiveProps、componentWillMount、componentWillUpdate這三個生命週期函數,但並非徹底取代,例如componentWillReceiveProps在只有父組件從新渲染時觸發,但此函數在每次渲染以前都會被觸發!它通常適用於讓state的值一直被props所控制。

getSnapshotBeforeUpdate( preProps, preState ) : 會在最近一次渲染以前被調用到,使得它能夠在組件更新以前從Dom中捕捉一些信息( 如滾動位置 ) , 此函數的任何返回值都將做爲參數傳遞到componentDidUpdate的第三個參數裏,此用法可用來UI處理滾動位置,不然儘可能不要去使用它!返回值是Snapshot值或者null。

componentDidUpdate( preProps, preState, snapshot ) : 用法同以前的React版本一致,但若是使用了getSnapshotBeforeUpdate( ),則它的返回值將做爲componentDidUpdate的第三個返回值,不然此參數爲unidentified。

Props直接給State傳值的問題:

應用場景例如 每一個用戶註冊後都會有本身設置的密碼,這時存儲好的密碼就是props,初始化爲空的密碼就是state,咱們須要去實現修改密碼的功能,作法確定是將props直接傳遞給state,而後改變state的值再傳輸到服務端完成此功能。

這個功能實現過程當中,咱們不能直接將props賦值給state,只有監聽props變化後纔去改變state,但有時候會遇到特殊狀況

componentWillReceiveProps(nextProps){
    if(nextProps.password !== this.props.password){
        this.setState({
            password: nextProps.password
                        })
        }
}複製代碼
看上去上面的方法能解決問題,可是再想一想看,若是切換用戶進行修改密碼時,先後用戶的密碼如出一轍,則state不會進行改變,頁面也不會從新渲染,也就至關於直接泄露密碼了。

//before React 16.3
componentWillReceiveProps(nextProps){
    if(nextProps.userId !== this.props.userId){
        this.setState({
            password: nextProps.password
                      })
        }
}

//after React 16.3
state = {
    userId : this.props.userId,
    password : this.props.password
}
static getDerivedStateFromProps( props,state ){
    if( props.userId !== state.userId ){
           return{
                userId: props.userId
                password: props.password
            }
      }
        return null; 
}複製代碼

這時判斷state改變條件改爲了監聽用戶的ID的變化,此時每次切換用戶進行修改密碼時都會使頁面從新渲染,每次props的值都將從新賦值給state。

若有不對,麻煩請指出錯誤。數組

相關文章
相關標籤/搜索