摘要:前言自從發布之后,更新速度日新月異,而生命周期也隨之改變,雖然原有的一些生命周期函數面臨廢棄,但理解其背后更新的機制也是一種學習在這里根據官方文檔以及社區上其他優秀的文章進行一個對于生命周期的總結,大致上分為以下三個模塊新老生命周期的區別為
前言
自從React發布Fiber之后,更新速度日新月異,而生命周期也隨之改變,雖然原有的一些生命周期函數面臨廢棄,但理解其背后更新的機制也是一種學習
在這里根據官方文檔以及社區上其他優秀的文章進行一個對于生命周期的總結,大致上分為以下三個模塊
新老生命周期的區別
為什么數據獲取要在componentDidMount中進行
為什么要改變生命周期
新老生命周期的區別新的生命周期增加了static getDerivedStateFromProps()以及getSnapshotBeforeUpdate(),廢棄了原有的componentWillMount()、componentWillUpdate()以及componentWillReceiveProps(),
分別如以下圖
原生命周期:
新生命周期(圖引用自React v16.3之后的組件生命周期函數):
為什么數據獲取要在componentDidMount中進行作者一開始也喜歡在React的willMount函數中進行異步獲取數據(認為這可以減少白屏的時間),后來發現其實應該在didMount中進行。
首先,分析一下兩者請求數據的區別:
componentWillMount獲取數據:
執行willMount函數,等待數據返回
執行render函數
執行didMount函數
數據返回, 執行render
didMount獲取數據:
執行willMount函數
執行render函數
執行didMount函數, 等待數據返回
數據返回, 執行render
很明顯,在willMount中獲取數據,可以節省時間(render函數和didMount函數的執行時間),但是為什么我們還要在didMount中獲取數據
如果使用服務端渲染的話,willMount會在服務端和客戶端各自執行一次,這會導致請求兩次(接受不了~),而didMount只會在客戶端進行
在Fiber之后, 由于任務可中斷,willMount可能會被執行多次
willMount會被廢棄,目前被標記為不安全
節省的時間非常少,跟其他的延遲情況相比,這個優化可以使用九牛一毛的形容(為了這么一點時間而一直不跟進技術的發展,得不償失),并且render函數是肯定比異步數據到達先執行,白屏時間并不能減少
關于第一點,如果你想在服務端渲染時先完成數據的展示再一次性給用戶,官方的推薦做法是用constructor代替willMount
為什么要改變生命周期從上面的生命周期的圖中可以看出,被廢棄的三個函數都是在render之前,因為fiber的出現,很可能因為高優先級任務的出現而打斷現有任務導致它們會被執行多次
另外的一個原因則是,React想約束使用者,好的框架能夠讓人不得已寫出容易維護和擴展的代碼,這一點又是從何談起,我們可以從新增加以及即將廢棄的生命周期分析入手
componentWillMoun首先這個函數的功能完全可以使用componentDidMount和constructor來代替,異步獲取的數據的情況上面已經說明了,而如果拋去異步獲取數據,其余的即是初始化而已,這些功能都可以在constructor中執行,除此之外,如果我們在willMount中訂閱事件,但在服務端這并不會執行willUnMount事件,也就是說服務端會導致內存泄漏
所以componentWillMount完全可以不使用,但使用者有時候難免因為各種各樣的情況(如作者犯渾)在componentWillMount中做一些操作,那么React為了約束開發者,干脆就拋掉了這個API
componentWillReceiveProps在老版本的 React 中,如果組件自身的某個 state 跟其 props 密切相關的話,一直都沒有一種很優雅的處理方式去更新 state,而是需要在 componentWillReceiveProps 中判斷前后兩個 props 是否相同,如果不同再將新的 props 更新到相應的 state 上去。這樣做一來會破壞 state 數據的單一數據源,導致組件狀態變得不可預測,另一方面也會增加組件的重繪次數。類似的業務需求也有很多,如一個可以橫向滑動的列表,當前高亮的 Tab 顯然隸屬于列表自身的狀態,但很多情況下,業務需求會要求從外部跳轉至列表時,根據傳入的某個值,直接定位到某個 Tab。 本段引用自React v16.3 版本新生命周期函數淺析及升級方案
為了解決這些問題,React引入了第一個新的生命周期
static getDerivedStateFromProps可以先看一下兩者在使用上的區別:
原有的代碼
新的代碼
這樣看似乎沒有什么改變,特別是當我們把this,tabChange也放在didUpdate中執行時(正確做法),完全沒有不同,但這也是我們一開始想說的,React通過API來約束開發者寫出更好的代碼,而新的使用方法有以下的優點
getDSFP是靜態方法,在這里不能使用this,也就是一個純函數,開發者不能寫出副作用的代碼
開發者只能通過prevState而不是prevProps來做對比,保證了state和props之間的簡單關系以及不需要處理第一次渲染時prevProps為空的情況
基于第一點,將狀態變化(setState)和昂貴操作(tabChange)區分開,更加便于 render 和 commit 階段操作或者說優化。
componentWillUpdate與 componentWillReceiveProps 類似,許多開發者也會在 componentWillUpdate 中根據 props 的變化去觸發一些回調。但不論是 componentWillReceiveProps 還是 componentWillUpdate,都有可能在一次更新中被調用多次,也就是說寫在這里的回調函數也有可能會被調用多次,這顯然是不可取的。與 componentDidMount 類似,componentDidUpdate 也不存在這樣的問題,一次更新中 componentDidUpdate 只會被調用一次,所以將原先寫在 componentWillUpdate 中的回調遷移至 componentDidUpdate 就可以解決這個問題。本段引用自React v16.3 版本新生命周期函數淺析及升級方案
另外一種情況則是我們需要獲取DOM元素狀態,但是由于在fiber中,render可打斷,可能在willMount中獲取到的元素狀態很可能與實際需要的不同,這個通常可以使用第二個新增的生命函數的解決
getSnapshotBeforeUpdategetSnapshotBeforeUpdate(prevProps, prevState) // 返回的值作為componentDidUpdate的第三個參數
與willMount不同的是, getSnapshotBeforeUpdate會在最終確定的render執行之前執行,也就是能保證其獲取到的元素狀態與didUpdate中獲取到的元素狀態相同,這里官方提供了一段參考代碼:
隨著React Fiber的落地,許多功能都將開始改變,但本質上是換湯不換藥,很多時候都是React為了開發者寫出更好的代碼而做的改變,當然這也是React的厲害之處,通過框架來約束開發者!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101592.html
摘要:簡單的舉下例子如等生命周期以及的事件即為異步更新,這里不顯示具體代碼。因為只有當父組件后才傳給子組件,那么如果要變成同步的,就需要放棄。 前言 在看React的官方文檔的時候, 發現了這么一句話,State Updates May Be Asynchronous,于是查詢了一波資料, 最后歸納成以下3個問題 setState為什么要異步更新,它是怎么做的? setState什么時候會...
摘要:三種的區別即對應中的值,如,服務器對任務都返回同一個,具體的路徑由瀏覽器區分,因為瀏覽器不會發送后面的值給服務器。如果是即變成這樣,,所以要對服務器配置不同的返回不同的資源。就是沒有的情況,比如。 三種Router的區別 1. HashRouter: 即對應url中的hash值,如xx.com/#/a、xx.com/#/a/b, 服務器對任務url都返回同一個url,具體的路徑由瀏覽器...
摘要:簡介是一種搭建客戶端的應用架構,更像是一種模式而不是一個框架。 簡介 Flux是一種搭建WEB客戶端的應用架構,更像是一種模式而不是一個框架。 特點 單向數據流 showImg(https://segmentfault.com/img/remote/1460000018128072?w=1300&h=708); 與MVC的比較 1.傳統的MVC如下所示(是一個雙向數...
摘要:前提最近通過閱讀官方文檔的事件模塊,有了一些思考和收獲,在這里記錄一下調用方法時需要手動綁定先從一段官方代碼看起代碼中的注釋提到了一句話的綁定是必須的,其實這一塊是比較容易理解的,因為這并不是的一個特殊點,而是這門語言的特性。 前提 最近通過閱讀React官方文檔的事件模塊,有了一些思考和收獲,在這里記錄一下~ 調用方法時需要手動綁定this 先從一段官方代碼看起: showImg(...
摘要:系列文章系列第一篇基礎雜記系列第二篇插件機制雜記系列第三篇流程雜記前言公司的前端項目基本都是用來做工程化的,而雖然只是一個工具,但內部涉及到非常多的知識,之前一直靠來解決問題,之知其然不知其所以然,希望這次能整理一下相關的知識點。 系列文章 Webpack系列-第一篇基礎雜記 Webpack系列-第二篇插件機制雜記 Webpack系列-第三篇流程雜記 前言 公司的前端項目基本都是用...
閱讀 2735·2021-11-22 15:22
閱讀 1643·2021-11-22 14:56
閱讀 3620·2021-09-22 15:12
閱讀 2408·2021-09-02 15:41
閱讀 2128·2021-08-27 16:26
閱讀 1118·2019-08-30 15:55
閱讀 2144·2019-08-29 17:30
閱讀 672·2019-08-29 16:26