首頁 > 軟體

React生命週期

2020-09-24 09:00:29

React生命週期分為15和16兩個不同的版本

React15生命週期

React15有四個不同的階段

  • 初始化(initialization)
  • 掛載階段(Mounting)
  • 更新階段(Updating)
  • 解除安裝階段

初始化

constructor()

  • 元件一創建就會呼叫 es6 class類中的 constructor 方法(最先執行)
  • super(props)`用來呼叫類的構造方法( constructor() ), 也將父元件的props注入給子元件,子元件中props只讀不可變,state可變
  • constructor()用來做一些元件的初始化工作,如定義this.state的初始內容

掛載階段

componentWillMount()

在元件掛載到DOM前呼叫,且只會被呼叫一次,在這邊呼叫this.setState不會引起元件重新渲染,也可以把寫在這邊的內容提前到constructor()中,所以項目中很少用,它代表的過程是元件已經經歷了constructor()初始化資料後,但是還未渲染DOM時。

render()

根據元件的props和state(兩者的重傳遞和重賦值,無論值是否有變化,都可以引起元件重新render) ,當父元件的 render 函數被運行時, 它的子元件的 render 函數也會被重新運行

return 一個React元素(描述元件,即JSX模板),不負責元件實際渲染工作,之後由React自身根據此元素去渲染出頁面DOM。render是純函數(Pure function:函數的返回結果只依賴於它的參數;函數執行過程裡面沒有副作用),不能在裡面執行this.setState,會有改變元件狀態的副作用。

componentDidMount()

元件掛載到DOM後呼叫,且只會被呼叫一次

更新階段

componentWillReceiveProps(nextProps)

  • 只跟父元件傳過來的 props 的變化有關,所以只有能接受 props 參數的子元件才有這個方法
  • 此方法只調用於props引起的元件更新過程中,參數nextProps是父元件傳給當前元件的新props
  • 而且這個元件第一次存在於父元件的是時候不會被執行(就是第一次不會執行,以後如果 nextProps 參數有變化才會被執行

shouldComponentUpdate(nextProps, nextState)

  • 主要用於效能優化(部分更新)
  • 唯一用於控制組件重新渲染的生命週期,由於在react中,setState以後,state發生變化,元件會進入重新渲染的流程,在這裡return false可以阻止元件的更新
  • 因為react父元件的重新渲染會導致其所有子元件的重新渲染,這個時候其實我們是不需要所有子元件都跟著重新渲染的,因此需要在子元件的該生命週期中做判斷

componentWillUpdate(nextProps, nextState)

在呼叫render方法前執行,在這邊可執行一些元件更新發生前的工作,一般較少用

render

componentDidUpdate(prevProps, prevState)

此方法在元件更新後被呼叫,可以操作元件更新的DOM,prevProps和prevState這兩個參數指的是元件更新前的props和state

解除安裝階段

componentWillUnmount

此方法在元件被解除安裝前呼叫,可以在這裡執行一些清理工作,比如清楚元件中使用的定時器,清楚componentDidMount中手動創建的DOM元素等,以避免引起記憶體洩漏。

React16生命週期

新引入了兩個新的生命週期函數

  • getDerivedStateFromProps(nextProps, prevState)
  • getSnapshotBeforeUpdate(prevProps, prevState)

getDerivedStateFromProps(nextProps, prevState)

  • 它應該返回一個物件來更新狀態,或者返回null來不更新任何內容
  • 代替componentWillReceiveProps()。老版本中的componentWillReceiveProps()方法判斷前後兩個 props 是否相同,如果不同再將新的 props 更新到相應的 state 上去。這樣做一來會破壞 state 資料的單一資料來源,導致元件狀態變得不可預測,另一方面也會增加元件的重繪次數。在 componentWillReceiveProps 中,我們一般會做以下兩件事,一是根據 props 來更新 state,二是觸發一些回撥,如動畫或頁面跳轉等。在老版本的 React 中,這兩件事我們都需要在 componentWillReceiveProps 中去做。而在新版本中,官方將更新 state 與觸發回撥重新分配到了 getDerivedStateFromProps 與 componentDidUpdate 中,使得元件整體的更新邏輯更為清晰。而且在 getDerivedStateFromProps 中還禁止了元件去訪問 this.props,強制讓開發者去比較 nextProps 與 prevState 中的值,以確保當開發者用到 getDerivedStateFromProps 這個生命週期函數時,就是在根據當前的 props 來更新元件的 state,而不是去做其他一些讓元件自身狀態變得更加不可預測的事情

getSnapshotBeforeUpdate(prevProps, prevState)

代替componentWillUpdate。常見的 componentWillUpdate 的用例是在元件更新前,讀取當前某個 DOM 元素的狀態,並在 componentDidUpdate 中進行相應的處理。

這兩者的區別在於:

  • 在 React 開啟非同步渲染模式後,在 render 階段讀取到的 DOM 元素狀態並不總是和 commit 階段相同,這就導致在componentDidUpdate 中使用 componentWillUpdate 中讀取到的 DOM 元素狀態是不安全的,因為這時的值很有可能已經失效了。
  • getSnapshotBeforeUpdate 會在最終的 render 之前被呼叫,也就是說在 getSnapshotBeforeUpdate 中讀取到的 DOM 元素狀態是可以保證與 componentDidUpdate 中一致的。
    此生命週期返回的任何值都將作為參數傳遞給componentDidUpdate()。

參考自

https://www.jianshu.com/p/b331d0e4b398

https://www.jianshu.com/p/2b2d1da16947


IT145.com E-mail:sddin#qq.com