生命周期 用户可以操作dom_React 生命周期的打怪升级之路
截止目前為止 React 已經發布了 v16.12.0 版本, React 生命周期也是日常開發低頭不見,抬頭見的狗子,可惜狗子它變了。
改變原因
v16.3 版本之前, React 中的更新操作是同步的,這可能會導致性能問題。
舉個例子,假如有一個龐大的模塊里面嵌套超級多的組件,一旦最頂部的 render 方法執行了,然后依次執行組件的 render 方法,直到最底層組件。這個過程會導致主線程卡主。
官方為了解決這個問題,因此引入了 React Fiber,其解決思路是分片執行,一個更新過程被分為兩個階段(Phase):第一個階段 Reconciliation Phase 和第二階段 Commit Phase。
在第一階段 Reconciliation Phase,React Fiber 會找出需要更新哪些 DOM,這個階段是可以被打斷的;但是到了第二階段 Commit Phase,那就一鼓作氣把 DOM 更新完,絕不會被打斷。
而這兩個階段也對應到不同的生命周期:
第一階段
- componentWillMount
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
第二階段
- componentDidMount
- componentDidUpdate
- componentWillUnmount
可以看看這個例子:Fiber vs Stack Demo
變更對比
以前:
現在( v16.3 ):
對比上下兩張圖,發現 React 廢棄了以下方法:
- componentWillMount
- componentWillReceiveProps
- componentWillUpdate
這里需要說明一下:為了做到版本版本兼容 增加 UNSAFE_componentWillMount,UNSAFE_componentWillReceiveProps和UNSAFE_componentWillUpdate方法,新舊方法都能使用,但使用舊方法,開發模式下會有紅色警告,在 React v17 更新時會徹底廢棄。
新增了方法如下:
- getDerivedStateFromProps
- getSnapshotBeforeUpdate
階段梳理
下面從三個階段(掛載、更新、卸載)梳理下生命周期方法。
constructor 構造函數
執行的生命周期方法,如果需要做一些初始化操作,比如初始化 state, 反正則無需為 React 組件實現構造函數。
getDerivedStateFromProps
當組件實例化的時候,這個方法替代了 componentWillMount(),而當接收到新的 props 時,該方法替代了 componentWillReceiveProps() 和 componentWillUpdate()。
static getDerivedStateFromProps(nextProps, prevState)其中 v16.3 版本中 re-rendering 之后此方法不會被調用,而 v16.4 版本中 re-rendering 之后都會調用此方法,這意味及時的 props 未發生改變,一旦父組件發生 re-rendering 那么子組件的該方法依然會被調用。
componentWillMount/UNSAVE_componentWillMount (即將廢棄)
部分同學日常會把數據請求放在該方法內,以便于快速獲取數據并展現,我的理解再怎么快,也快不過首次 render,并且 React Fiber 執行機制的原因,會導致該方法被執行多次,這也意味著接口被請求多次。因此該方法在 v17 版本以后將被徹底廢棄。
componentDidMount
在組件掛載完成后調用,且全局只調用一次。可以在這里使用 refs,獲取真實 dom 元素。該鉤子內也可以發起異步請求,并在異步請求中可以進行 setState。
componentWillReceiveProps/UNSAFE_componentWillReceiveProps (即將廢棄)
被 getDerivedStateFromProps 方法取代。
shouldComponentUpdate
每次調用 setState 后都會調用 shouldComponentUpdate 判斷是否需要重新渲染組件。默認返回 true,需要重新 render。返回 false 則不觸發渲染。在比較復雜的應用里,有一些數據的改變并不影響界面展示,可以在這里做判斷,優化渲染效率。
componentWillUpdate
依舊是 React Fiber 執行機制的原因,在該方法記錄 DOM 狀態就不在準確了。
getSnapshotBeforeUpdate
觸發該方法的實際,是在更新 DOM 之前的一瞬間,比 componentWillUpdate 記錄的 DOM 狀態更為精確。
componentDidUpdate
除了首次 render 之后調用 componentDidMount,其它 render 結束之后都是調用 componentDidUpdate。
componentWillUnmount
組件被卸載的時候調用。一般在 componentDidMount 里面注冊的事件需要在這里刪除。
總結
由于 React 同步更新組件的原因,會引起性能問題,造成主線程卡死,因此引入 React Fiber 對核心算法的一次重新實現。 緊接著發現, React Fiber 會讓部分生命周期方法行多次,而廢除這部分方法,引入新方法。
參考文章:
React Fiber 是什么
React v16.3 之后的組件生命周期函數
淺談 React Fiber 及其對 lifecycles 造成的影響
講講今后 React 異步渲染帶來的生命周期變化
React 新舊生命周期的思考理解
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的生命周期 用户可以操作dom_React 生命周期的打怪升级之路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springboot 访问html_Sp
- 下一篇: 计算机与人脑_看!自行车成精了...清华