自從React發佈Fiber以後,更新速度突飛猛進,而生命週期也隨之改變,雖然原有的一些生命週期函數面臨廢棄,但理解其背後更新的機制也是一種學習html
在這裏根據官方文檔以及社區上其餘優秀的文章進行一個對於生命週期的總結,大體上分爲如下三個模塊react
新的生命週期增長了static getDerivedStateFromProps()以及getSnapshotBeforeUpdate(),廢棄了原有的componentWillMount()、componentWillUpdate()以及componentWillReceiveProps(),
分別如如下圖 安全
原生命週期: 框架
新生命週期(圖引用自React v16.3以後的組件生命週期函數): 異步
做者一開始也喜歡在React的willMount函數中進行異步獲取數據(認爲這能夠減小白屏的時間),後來發現其實應該在didMount中進行。函數
首先,分析一下二者請求數據的區別: 學習
componentWillMount獲取數據:優化
didMount獲取數據:this
很明顯,在willMount中獲取數據,能夠節省時間(render函數和didMount函數的執行時間),可是爲何咱們還要在didMount中獲取數據spa
關於第一點,若是你想在服務端渲染時先完成數據的展現再一次性給用戶,官方的推薦作法是用constructor代替willMount
從上面的生命週期的圖中能夠看出,被廢棄的三個函數都是在render以前,由於fiber的出現,極可能由於高優先級任務的出現而打斷現有任務致使它們會被執行屢次
另外的一個緣由則是,React想約束使用者,好的框架可以讓人不得已寫出容易維護和擴展的代碼,這一點又是從何談起,咱們能夠重新增長以及即將廢棄的生命週期分析入手
首先這個函數的功能徹底可使用componentDidMount和constructor來代替,異步獲取的數據的狀況上面已經說明了,而若是拋去異步獲取數據,其他的便是初始化而已,這些功能均可以在constructor中執行,除此以外,若是咱們在willMount中訂閱事件,但在服務端這並不會執行willUnMount事件,也就是說服務端會致使內存泄漏
因此componentWillMount徹底能夠不使用,但使用者有時候不免由於各類各樣的狀況(如做者犯渾)在componentWillMount中作一些操做,那麼React爲了約束開發者,乾脆就拋掉了這個API
在老版本的 React 中,若是組件自身的某個 state 跟其 props 密切相關的話,一直都沒有一種很優雅的處理方式去更新 state,而是須要在 componentWillReceiveProps 中判斷先後兩個 props 是否相同,若是不一樣再將新的 props 更新到相應的 state 上去。這樣作一來會破壞 state 數據的單一數據源,致使組件狀態變得不可預測,另外一方面也會增長組件的重繪次數。相似的業務需求也有不少,如一個能夠橫向滑動的列表,當前高亮的 Tab 顯然隸屬於列表自身的狀態,但不少狀況下,業務需求會要求從外部跳轉至列表時,根據傳入的某個值,直接定位到某個 Tab。 本段引用自React v16.3 版本新生命週期函數淺析及升級方案
爲了解決這些問題,React引入了第一個新的生命週期
能夠先看一下二者在使用上的區別:
原有的代碼
新的代碼
這樣看彷佛沒有什麼改變,特別是當咱們把this,tabChange也放在didUpdate中執行時(正確作法),徹底沒有不一樣,但這也是咱們一開始想說的,React經過API來約束開發者寫出更好的代碼,而新的使用方法有如下的優勢
與 componentWillReceiveProps 相似,許多開發者也會在 componentWillUpdate 中根據 props 的變化去觸發一些回調。但不管是 componentWillReceiveProps 仍是 componentWillUpdate,都有可能在一次更新中被調用屢次,也就是說寫在這裏的回調函數也有可能會被調用屢次,這顯然是不可取的。與 componentDidMount 相似,componentDidUpdate 也不存在這樣的問題,一次更新中 componentDidUpdate 只會被調用一次,因此將原先寫在 componentWillUpdate 中的回調遷移至 componentDidUpdate 就能夠解決這個問題。 本段引用自React v16.3 版本新生命週期函數淺析及升級方案
另一種狀況則是咱們須要獲取DOM元素狀態,可是因爲在fiber中,render可打斷,可能在willMount中獲取到的元素狀態極可能與實際須要的不一樣,這個一般可使用第二個新增的生命函數的解決
getSnapshotBeforeUpdate(prevProps, prevState) // 返回的值做爲componentDidUpdate的第三個參數
與willMount不一樣的是, getSnapshotBeforeUpdate會在最終肯定的render執行以前執行,也就是能保證其獲取到的元素狀態與didUpdate中獲取到的元素狀態相同,這裏官方提供了一段參考代碼:
隨着React Fiber的落地,許多功能都將開始改變,但本質上是換湯不換藥,不少時候都是React爲了開發者寫出更好的代碼而作的改變,固然這也是React的厲害之處,經過框架來約束開發者!