2021-05-12 14:32:11
React生命週期
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()。
參考自
相關文章