追求卓越一諾千金

藍藍設計--运城特产,2011年成立|--小米手机ppt,主創清華團隊-陈思远微博,專注軟件和互聯網ui設計開發|_3号彩票的软件。擅長企業信息化管理|--258彩票注册送38、監控-__19手机网、大數據軟件UIUE谘詢和設計開發服務-茶叶生意。立足UI|-|塞缪尔比林斯利博士,好好學習|-银彩娱乐app,天天進步--镇赉吧!


重新學習 React (一) 生命周期_-非洲色图,Fiber 調度和更新機製

2019-6-13 釋然 前端及開發文章及欣賞


如果您想訂閱本博客內容|-震荡波补丁,每天自動發到您的郵箱中|_-078彩票软件安全吗, 請點這裏

前幾天麵試問道 react 的相關知識_键盘自动按键器,對我打擊比較大-|银行职员张洁,感覺對 react 認識非常膚淺_||诺基亚ace,所以在這裏重新梳理一下_-铁梨花41,想想之前沒有仔細思考過的東西-360彩票杀号定胆。

另外有說的不對的地方還請幫我指正一下__铠甲战士之勇者之路无敌版,先謝謝各位啦-_西凉剧情诗句。

目錄索引-_|烈女蒋究:

什麼是生命周期和調度-宿松政府网?

React 有一套合理的運行機製去控製程序在指定的時刻該做什麼事-_-35彩票,當一個生命周期鉤子被觸發後-_-设备保修卡,緊接著會有下一個鉤子__沈阳洗浴特服,直到整個生命周期結束--芳草集小米草眼霜。

生命周期

生命周期代表著每個執行階段|_15700牛蚌彩票开奖现场,比如組件初始化_|陈怡阳台门,更新完成|陆地蟹,馬上要卸載等等_|午夜神,React 會在指定的時機執行相關的生命周期鉤子_-河南马桶解说,使我們可以有機在程序運行中會插入自己的邏輯|__石蜡的熔点。

調度

我們寫代碼的時候往往會有很多組件以及他們的子組件--|注册送28元体验金app彩票,各自調用不同的生命周期-||张翰郑爽2017金鹰同台,這時就要解決誰先誰後的問題|木樨园服装市场,在 react v16 之前是采用了遞歸調用的方式一個一個執行_|_永盛国际手机彩票,而在現在 v16 的版本中則采用了與之完全不同的處理(調度)方式|-陈思远微博,名叫 Fiber|-_娱乐天地彩票平台,這個東西 facebook 做了有兩年時間-||105彩票靠谱吗,實現非常複雜|-_尊龙国际娱乐平台app。

具體 Fiber 它是一個什麼東西呢-_|爱肺金雪茄?不要著急||-芷江租房,我們先從最基本的生命周期鉤子看起--|刘一冰。

React 生命周期詳解

首先看一下 React V16.4 後的生命周期概況(圖片來源

 

 

  • 從橫向看|-_093彩票靠谱吗,react 分為三個階段|-_168彩票官方开奖网:
    • 創建時
      • constructor() - 類構造器初始化
      • static getDerivedStateFromProps() - 組件初始化時主動觸發
      • render() - 遞歸生成虛擬 DOM
      • componentDidMount() - 完成首次 DOM 渲染
    • 更新時
      • static getDerivedStateFromProps() - 每次 render() 之前執行
      • shouldComponentUpdate() - 校驗是否需要執行更新操作
      • render() - 遞歸生成虛擬 DOM
      • getSnapshotBeforeUpdate() - 在渲染真實 DOM 之前
      • componentDidUpdate() - 完成 DOM 渲染
    • 卸載時
      • componentWillUnmount() - 組件銷毀之前被直接調用

一些幹貨

  • 有三種方式可以觸發 React 更新_|我要身份证号码,props 發生改變||利玛窦是哪国人,調用 setState() 和調用 forceUpdate()
  • static getDerivedStateFromProps() 這個鉤子會在每個更新操作之前(即使props沒有改變)執行一次_重庆伟岸,使用時應該保持謹慎_洪洞贴吧。
  • componentDidMount() 和 componentDidUpdate() 執行的時機是差不多的-_观赏鱼之家zadull水族,都在 render 之後||-门铃音效,隻不過前者隻在首次渲染後執行||gts3370,後者首次渲染不會執行
  • getSnapshotBeforeUpdate() 執行時可以獲得隻讀的新 DOM 樹---爱尚满屋,此函數的返回值為 componentDidUpdate(prevProps, prevState, snapshot) 的第三個參數

嚐試理解 Fiber

關於 Fiber_-金牛区国土局,強烈建議聽一下知乎上程墨Morgan的 live 《深入理解React v16 新功能》--河南四套,這裏潛水員的例子和圖片也是引用於此 live__我要看一级片。

背景

我們知道 React 是通過遞歸的方式來渲染組件的-|童装订货会,在 V16 版本之前的版本裏_|至尊联盟彩种平台,當一個狀態發生變更時_|18135期七星彩开奖号码,react 會從當前組件開始_|许宗衡简历,依次遞歸調用所有的子組件生命周期鉤子-_|01彩票软件平台安全吗,而且這個過程是同步執行的且無法中斷的-__现任国家领导人排名,一旦有很深很深的組件嵌套||致青春qvod,就會造成嚴重的頁麵卡頓---芜湖德尔福派克招聘,影響用戶體驗|_|亿发国际。

React 在V16版本之前的版本裏引入了 Fiber 這樣一個東西-_|计提福利费,它的英文涵義為纖維|||中国石油价格表,在計算機領域它排在在進程和線程的後麵__配角曹轩宾,雖然 React 的 Fiber 和計算機調度裏的概念不一樣-_-小时代 快乐大本营,但是可以方便對比理解_劲舞团舞团名字,我們大概可以想象到 Fiber 可能是一個比線程還短的時間片段-电视剧军刺。

Fiber 到底做了什麼事

Fiber 把當前需要執行的任務分成一個個微任務|_|龙玛显脉片,安排優先級|_-阿杰路,然後依次處理-__洗浴服务,每過一段時間(非常短__-穿越神墓之何为逆天,毫秒級)就會暫停當前的任務--|乒乓球教学视频下载,查看有沒有優先級較高的任務-_抱抱装,然後暫停(也可能會完全放棄)掉之前的執行結果--|链家地产司歌歌词,跳出到下一個微任務_余庆教育网。同時 Fiber 還做了一些優化_|siro 1440,可以保持住之前運行的結果以到達複用目的-无翼乌全彩无漫画大全老师。

舉個潛水員的例子

我們可以把調度當成一個潛水員在海底尋寶|--马云投资云联惠5000亿,v16 之前是通過組件遞歸的方式進行尋寶_高三毕业班主任寄语,從父組件開始一層一層深入到最裏麵的子組件||吉林省中小学教师研修网,也就是如下圖所示__|诸沁微。

 

 

 

而替換成了 Fiber 後__丝诺萄官网,海底變成的狹縫(簡單理解為遞歸變成了遍曆)|-1博平台彩票如何,潛水員會每隔一小段時間浮出水麵||-昨夜裙带解,看看有沒有其他尋寶任務||_宠物花卉。注意此時沒有尋到寶藏的話--|众发娱乐app,那麼之前潛水的時間就浪費了--_阳泉中行吧。就這樣潛水員會一直下潛和冒泡|_至爱亲朋电视剧,具體如下圖所示_|0567好彩官方版苹果。

 

 

 

引入 Fiber 後帶來的三個階段

從生命周期那張圖片縱向來看-_049c彩票,Fiber 將整個生命周期分成了三個階段-||100%竞彩篮球分析预测:

  • render 階段
    • 由於 Fiber 會時不時跳出任務|-|金橘花,然後重新執行|_陈姿彤微博,會導致該階段的生命周期調用多次的現象||2018大乐透开奖号全部,所以 React V16 之前 componentWillMount()--上海中潭癫痫能治愈,componentWillUpdate()_-网曝 查开房 网址,componentWillReceiveProps() 的三個生命周期鉤子被加上了 UNSAFE 標記
    • 這個階段效率不一定會比之前同步遞歸來的快|-阴道老化,因為會有任務跳出重做的性能損耗-||2009手机qq,但是從宏觀上看_|诺基亚2700c电子书,它不斷執行了最高優先級(影響用戶使用體驗)的任務__|栾城黑社会,所以用戶使用起來會比以前更加的流暢
    • 這個階段的生命周期鉤子可能會重複調用_众投彩,建議隻寫無副作用的代碼
  • pre-commit 階段
    • 該階段 DOM 已經形成陈丽华前夫,但還是隻讀狀態
    • 這個階段組件狀態不會再改變
  • commit 階段
    • 此時的 DOM 可以進行操作
    • 這個階段組件已經完成更新_-_7k7小游戏大全,可以寫一些有副作用的代碼和添加其它更新操作|-|慢生活。

簡而言之|||掌上平台336时时彩:以 render() 為界_-|陈世祯,之前執行的生命周期都有可能會打斷並多次調用-||1953年1月8日人民日报,之後的生命周期是不可被打斷的且隻會調用一次-_|运盛彩票作弊。所以盡量把副作用的代碼放在隻會執行一次的 commit 階段-亿博那个可信吗。

其它生命周期鉤子

除了上麵常用的鉤子_|劫后余生3 9,React 還提供了如下鉤子|_-007a私募内线:

  • static getDerivedStateFromError() 在 render 階段執行-_|bumper信号圈,通過返回 state 更新組件狀態
  • componentDidCatch() 在 commit 階段執行_|3b五码遗漏彩票大赢家,可以放一些有副作用的代碼

更新機製

理解了生命周期和三個執行階段-|-朱志恒,就可以比較容易理解組件狀態的更新機製了_-_亿彩彩票手机版登录。

setState()

這個方法可以讓我們更新組件的 state 狀態||助赢论坛。第一個參數可以是對象__寂寞先生 刘悦,也可以是 updater 函數-|长恨春寻无觅处,如果是函數-_菲亚斯,則會接受當前的 state 和 props 作為參數_||258彩票平台。第二個參數為函數_|12月新规都是好消息,是在 commit 階段後執行-__陕西高职院校排名,準確的說是在 componentDidUpdate() 後執行-|众彩娱乐可以举报吗。

setState() 的更新過程是異步的(除非綁定在 DOM 事件中或寫在 setTimeout 裏)|_33选7大星彩票开奖,而且會在最後合並所有的更新-|1288彩票多少才得提现?,如下--|18146大乐透开奖结果:

Object.assign( previousState,
  {quantity: state.quantity + 1},
  {quantity: state.quantity + 1},
  ...
)
複製代碼

之所以設計成這樣|_11选5开奖结果查询山东,是為了避免在一次生命周期中出現多次的重渲染-|-盈彩在线怎么玩,影響頁麵性能__322彩票。

forceUpdate()

如果我們想強製刷新一個組件--|掉下了眼泪音译歌词,可以直接調用該方法-_重庆李俊案,調用時會直接執行 render() 這個函數而跳過 shouldComponentUpdate()-_-亿客隆彩票网站。

舉個極端例子

function wait() { return new Promise(resolve => {
    setTimeout(() => {
      resolve(); console.log("wait");
    }, 0);
  });
} //......省略組件創建 async componentDidMount() { await wait(); this.setState({ name: "new name" }); console.log("componentDidMount");
}

componentDidUpdate() { console.log("componentDidUpdate");
}

render() { console.log(this.state); return null } //......省略組件創建 // 輸出結果如下 // wait // {name: "new name"} // componentDidUpdate // componentDidMount // 注意 componentDidUpdate 的輸出位置-_qq空间视频地址,一般情況下 // componentDidUpdate 都是在componentDidMount 後麵 // 執行的-_-祥康快车王晗,但是這裏因為setState 寫在了 await 後麵 // 所以情況相反_|魔尊火线1 3生化怒袭。 複製代碼

結語

了解 react 生命周期和更新機製確實有利於編寫代碼_-星光大道娃娃李烁,特別是當代碼量越來越大時-|2019生肖表图属猪,錯用的 setState 或生命周期鉤子都可能埋下越來越多的雷|-赫依伦,直到有一天無法維護|||固话积分查询。_|_高考是哪天。|-2011手机qq。

我的個人建議如下__|k7k小游戏大全:

  • 把副作用代碼通通放在 commit 階段__-众博国际,因為這個階段不會影響頁麵渲染性能
  • 盡可能不要使用 forceUpdate() 方法||0x00070001,借用 Evan You 的一句話||_众赢彩票娱乐平台注册,如果你發現你自己需要在 Vue 中做一次強製更新-青田石封门青,99.9% 的情況___花都开好了伴奏,是你在某個地方做錯了事
  • 隻要調用了 setState() 就會進行 render()|-|永胜国际app,無論 state 是否改變
  • 知道 setState() 更新的什麼時候是同步的__就医160网上预约,什麼時候是異步的-|小腻腻的博客,參見上文
  • 不要把 getDerivedStateFromProps() 當成是 UNSAFE_componentWillReceiveProps() 的替代品_|海安县高级中学,因為 getDerivedStateFromProps() 會在每次 render() 之前執行__|邵天罡,即使 props 沒有改變




藍藍設計www.jwrumpff.com )是一家專注而深入的界麵設計公司|-纤之瘦,為期望卓越的國內外企業提供卓越的UI界麵設計-_-郎酒股票代码、BS界麵設計 -|1211彩票、 cs界麵設計 _-保定热线测网速、 ipad界麵設計 _藤步阁、 包裝設計 |-劫后余生3 9、 圖標定製 __|37彩票是官方网站、 用戶體驗 |_诱捕野猪人、交互設計-||该隐打卡修斯、 網站建設 _-_美国乒乓球队、平麵設計服務|-106时时彩手机版。

標簽: 生命周期 React 重新學習 (一) Fiber 調度和更新機製 « 淺入 React 生命周期相關(二)更新生命周期 | 移動端和PC端交互設計上的區別»


訂閱Rss