1. 程式人生 > >更新階段的生命周期

更新階段的生命周期

進行 可變 lean set 技術 內部數據 生命 attr element

更新階段的生命周期

  • componentWillReceiveProps(object nextProps) :當掛載的組件接收到新的props時被調用。此方法應該被用於比較this.props 和 nextProps以用於使用this.setState()執行狀態轉換。(組件內部數據有變化,使用state,但是在更新階段又要在props改變的時候改變state,則在這個生命周期裏面)

  • shouldComponentUpdate(object nextProps, object nextState) : -boolean 當組件決定任何改變是否要更新到DOM時被調用。作為一個 優化 實現比較this.props 和 nextProps 、this.state 和 nextState ,如果React應該跳過更新,返回false。

  • componentWillUpdate(object nextProps, object nextState) :在更新發生前被立即調用。你不能在此調用 this.setState()

  • componentDidUpdate(object prevProps, object prevState) : 在更新發生後被立即調用。(可以在DOM更新完之後,做一些收尾的工作)

Tips:

  • React的優化是基於 shouldComponentUpdate 的,該生命周期默認返回true,所以一旦prop或state有任何變化,都會引起重新render。

shouldComponentUpdate

react在每個組件生命周期更新的時候都會調用一個shouldComponentUpdate(nextProps, nextState)函數。它的職責就是返回true或false,true表示需要更新,false表示不需要,默認返回為true,即便你沒有顯示地定義 shouldComponentUpdate 函數。這就不難解釋上面發生的資源浪費了。

為了進一步說明問題,我們再引用一張官網的圖來解釋,如下圖( SCU表示shouldComponentUpdate,綠色表示返回true(需要更新),紅色表示返回false(不需要更新);vDOMEq表示虛擬DOM比對,綠色表示一致(不需要更新),紅色表示發生改變(需要更新)):

技術分享

根據渲染流程,首先會判斷shouldComponentUpdate(SCU)是否需要更新。如果需要更新,則調用組件的render生成新的虛擬DOM,然後再與舊的虛擬DOM對比(vDOMEq),如果對比一致就不更新,如果對比不同,則根據最小粒度改變去更新DOM;如果SCU不需要更新,則直接保持不變,同時其子元素也保持不變。

  • C1根節點,綠色SCU (true),表示需要更新,然後vDOMEq紅色,表示虛擬DOM不一致,需要更新。

  • C2節點,紅色SCU (false),表示不需要更新,所以C4,C5均不再進行檢查

  • C3節點同C1,需要更新

  • C6節點,綠色SCU (true),表示需要更新,然後vDOMEq紅色,表示虛擬DOM不一致,更新DOM。

  • C7節點同C2

  • C8節點,綠色SCU (true),表示需要更新,然後vDOMEq綠色,表示虛擬DOM一致,不更新DOM。

帶坑的寫法:

  • {...this.props} (不要濫用,請只傳遞component需要的props,傳得太多,或者層次傳得太深,都會加重shouldComponentUpdate裏面的數據比較負擔,因此,也請慎用spread attributes(<Component {...props} />))。

  • ::this.handleChange()。(請將方法的bind一律置於constructor)

  • this.handleChange.bind(this,id)

  • 復雜的頁面不要在一個組件裏面寫完。

  • 請盡量使用const element。

  • map裏面添加key,並且key不要使用index(可變的)。具體可參考 使用Perf工具研究React Key對渲染的影響

  • 盡量少用setTimeOut或不可控的refs、DOM操作。

  • 數據盡可能簡單明了,扁平化。

更新階段的生命周期