追求卓越一諾千金

藍藍設計_|城市热线,2011年成立|_|五菱双排加长小货车,主創清華團隊|_广州鸣人堂,專注軟件和互聯網ui設計開發-_莅临的意思。擅長企業信息化管理||智投彩票合法吗、監控-_-湖南移动梦网营业厅、大數據軟件UIUE谘詢和設計開發服務|_极品公子混在校园。立足UI___皇家马德里电影,好好學習___青山湖区教体局,天天進步--塔河吧!


重新學習 React (一) 生命周期农行网银维护,Fiber 調度和更新機製

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


如果您想訂閱本博客內容__-106平台彩票iOS版,每天自動發到您的郵箱中|_-云谷彩票手机版登录, 請點這裏

前幾天麵試問道 react 的相關知識|-_卓越分分彩计划,對我打擊比較大|--春天的作文200字,感覺對 react 認識非常膚淺_-_娱乐天地点检安卓,所以在這裏重新梳理一下-叫兽全集,想想之前沒有仔細思考過的東西|_-盈彩吧是正规的吗。

另外有說的不對的地方還請幫我指正一下-注册银彩app,先謝謝各位啦_如果云知道 歌词。

目錄索引|_-壮警的烦恼(h) txt:

什麼是生命周期和調度-_|亿彩邀请码是多少?

React 有一套合理的運行機製去控製程序在指定的時刻該做什麼事_-|258彩票网代理,當一個生命周期鉤子被觸發後-_沧州市迎宾路小学,緊接著會有下一個鉤子_-_花中仙子是什么花,直到整個生命周期結束|-|运盛下载。

生命周期

生命周期代表著每個執行階段|造梦西游3爆率,比如組件初始化__|星际2人族大讲堂,更新完成-||盈彩是什么平台,馬上要卸載等等_--国际品牌洗发水,React 會在指定的時機執行相關的生命周期鉤子--河北区haobc,使我們可以有機在程序運行中會插入自己的邏輯--苏州新区人才市场现场招聘。

調度

我們寫代碼的時候往往會有很多組件以及他們的子組件__爵迹风津道14回全文,各自調用不同的生命周期_青岛火车站订票,這時就要解決誰先誰後的問題-邓超暧昧短信,在 react v16 之前是采用了遞歸調用的方式一個一個執行_-|钱学森女儿,而在現在 v16 的版本中則采用了與之完全不同的處理(調度)方式-|_娱乐天地苹果,名叫 Fiber-|-3号彩票代理,這個東西 facebook 做了有兩年時間手工毛衣外套,實現非常複雜_-无叶涡轮增压器。

具體 Fiber 它是一個什麼東西呢-|铺底流动资金?不要著急_-_四川地震感人故事,我們先從最基本的生命周期鉤子看起__|极品公子混在校园。

React 生命周期詳解

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

 

 

  • 從橫向看|_|都匀蓝宇装饰,react 分為三個階段_|何小萌萌萌新浪微博:
    • 創建時
      • constructor() - 類構造器初始化
      • static getDerivedStateFromProps() - 組件初始化時主動觸發
      • render() - 遞歸生成虛擬 DOM
      • componentDidMount() - 完成首次 DOM 渲染
    • 更新時
      • static getDerivedStateFromProps() - 每次 render() 之前執行
      • shouldComponentUpdate() - 校驗是否需要執行更新操作
      • render() - 遞歸生成虛擬 DOM
      • getSnapshotBeforeUpdate() - 在渲染真實 DOM 之前
      • componentDidUpdate() - 完成 DOM 渲染
    • 卸載時
      • componentWillUnmount() - 組件銷毀之前被直接調用

一些幹貨

  • 有三種方式可以觸發 React 更新__105彩票是否合法,props 發生改變--_长筒袜皮皮,調用 setState() 和調用 forceUpdate()
  • static getDerivedStateFromProps() 這個鉤子會在每個更新操作之前(即使props沒有改變)執行一次_|搞笑考卷,使用時應該保持謹慎||_711便利店图片。
  • componentDidMount() 和 componentDidUpdate() 執行的時機是差不多的_诺基亚5600,都在 render 之後||_花冈实太,隻不過前者隻在首次渲染後執行_|_肝病康复网,後者首次渲染不會執行
  • getSnapshotBeforeUpdate() 執行時可以獲得隻讀的新 DOM 樹_--说说电视记者这行吧,此函數的返回值為 componentDidUpdate(prevProps, prevState, snapshot) 的第三個參數

嚐試理解 Fiber

關於 Fiber_-|海马骑士7,強烈建議聽一下知乎上程墨Morgan的 live 《深入理解React v16 新功能》-_-1号平台下载安装,這裏潛水員的例子和圖片也是引用於此 live--捷安特770。

背景

我們知道 React 是通過遞歸的方式來渲染組件的_|阜宁二手房网,在 V16 版本之前的版本裏||武汉市教师教育网,當一個狀態發生變更時|星光大道娃娃李烁,react 會從當前組件開始_-药草悠悠芳草香,依次遞歸調用所有的子組件生命周期鉤子-重庆万盛黑山论坛,而且這個過程是同步執行的且無法中斷的--106在线彩票安卓,一旦有很深很深的組件嵌套|-丁丁和杨坤后场接吻,就會造成嚴重的頁麵卡頓|长江流域图,影響用戶體驗_--钟蕙芝。

React 在V16版本之前的版本裏引入了 Fiber 這樣一個東西-_|云霄门,它的英文涵義為纖維__云顶娱乐怎么提现,在計算機領域它排在在進程和線程的後麵||_靓眼网,雖然 React 的 Fiber 和計算機調度裏的概念不一樣-|-伯西来,但是可以方便對比理解||105彩票彩票大全,我們大概可以想象到 Fiber 可能是一個比線程還短的時間片段--恋狱和之匣。

Fiber 到底做了什麼事

Fiber 把當前需要執行的任務分成一個個微任務||_苏州博客门,安排優先級|钢轨标准,然後依次處理_|盈彩彩票是真是假,每過一段時間(非常短--剑气侠虹,毫秒級)就會暫停當前的任務_宜兴土特产,查看有沒有優先級較高的任務--诺基亚n79手机,然後暫停(也可能會完全放棄)掉之前的執行結果_|长信通,跳出到下一個微任務_-注册辉煌团队。同時 Fiber 還做了一些優化--_金逸国际影城影讯,可以保持住之前運行的結果以到達複用目的__n79论坛。

舉個潛水員的例子

我們可以把調度當成一個潛水員在海底尋寶--|青田封门青,v16 之前是通過組件遞歸的方式進行尋寶_|-qq游戏马,從父組件開始一層一層深入到最裏麵的子組件---234天天彩票app下载,也就是如下圖所示_|-恒大亚冠决赛时间。

 

 

 

而替換成了 Fiber 後||金天桥,海底變成的狹縫(簡單理解為遞歸變成了遍曆)_|塔罗牌大师tlp6868668,潛水員會每隔一小段時間浮出水麵|众彩网简介,看看有沒有其他尋寶任務|__369开奖网时时彩。注意此時沒有尋到寶藏的話_|烈女蒋究,那麼之前潛水的時間就浪費了|--中兴彩票ApP。就這樣潛水員會一直下潛和冒泡_--魔尊火线1 3生化怒袭,具體如下圖所示-|上海癫痫病中潭医院。

 

 

 

引入 Fiber 後帶來的三個階段

從生命周期那張圖片縱向來看|-|苏岑的博客,Fiber 將整個生命周期分成了三個階段|_言承旭和ella:

  • render 階段
    • 由於 Fiber 會時不時跳出任務|154大乐透彩票中奖号码,然後重新執行||-固定电话费查询,會導致該階段的生命周期調用多次的現象__永胜国际能挣钱吗,所以 React V16 之前 componentWillMount()-云顶娱乐每天送6金币,componentWillUpdate()--动情迹忆,componentWillReceiveProps() 的三個生命周期鉤子被加上了 UNSAFE 標記
    • 這個階段效率不一定會比之前同步遞歸來的快||7k7k7k7k7k小游戏,因為會有任務跳出重做的性能損耗_|无氨显影液,但是從宏觀上看_-变形记 美丽加减法,它不斷執行了最高優先級(影響用戶使用體驗)的任務|_-2010男篮世锦赛决赛,所以用戶使用起來會比以前更加的流暢
    • 這個階段的生命周期鉤子可能會重複調用__150号段,建議隻寫無副作用的代碼
  • pre-commit 階段
    • 該階段 DOM 已經形成--三水芦苞祖庙,但還是隻讀狀態
    • 這個階段組件狀態不會再改變
  • commit 階段
    • 此時的 DOM 可以進行操作
    • 這個階段組件已經完成更新_-_血族德鲁依,可以寫一些有副作用的代碼和添加其它更新操作-|武林风王洪强。

簡而言之-||烟熏枣:以 render() 為界|||优信彩票软件,之前執行的生命周期都有可能會打斷並多次調用_某小型火力发电厂,之後的生命周期是不可被打斷的且隻會調用一次-111彩票v11安卓版。所以盡量把副作用的代碼放在隻會執行一次的 commit 階段-__取暖歌词。

其它生命周期鉤子

除了上麵常用的鉤子|-仙缘 云朵朵之家,React 還提供了如下鉤子|_|36选7复式9个号多少钱:

  • static getDerivedStateFromError() 在 render 階段執行_||团结柱,通過返回 state 更新組件狀態
  • componentDidCatch() 在 commit 階段執行___我是歌手第10期排名,可以放一些有副作用的代碼

更新機製

理解了生命周期和三個執行階段-|雪豹雳剑,就可以比較容易理解組件狀態的更新機製了_柯露玛。

setState()

這個方法可以讓我們更新組件的 state 狀態-_|伯西来。第一個參數可以是對象|-娱乐天地客服联系,也可以是 updater 函數|-_堵车电影,如果是函數|_|长沙租房口碑网,則會接受當前的 state 和 props 作為參數__-致命交易市长放过我。第二個參數為函數-_订火车票网址,是在 commit 階段後執行|||青岛往事下载,準確的說是在 componentDidUpdate() 後執行__|防爆机器人布里茨。

setState() 的更新過程是異步的(除非綁定在 DOM 事件中或寫在 setTimeout 裏)_||海东人事局,而且會在最後合並所有的更新_惠蒙网qig6,如下_|qq炫舞答案每日更新:

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

之所以設計成這樣--_艾斯奥特曼怪兽图鉴,是為了避免在一次生命周期中出現多次的重渲染-_诺基亚5610软件下载,影響頁麵性能|_娱乐天地线路。

forceUpdate()

如果我們想強製刷新一個組件|-siro 1440,可以直接調用該方法-_湖南特岗计划信息管理系统,調用時會直接執行 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 的輸出位置|_御龙在天野蘑菇,一般情況下 // componentDidUpdate 都是在componentDidMount 後麵 // 執行的__义务教育课程标准实验教科书,但是這裏因為setState 寫在了 await 後麵 // 所以情況相反|-_笑刑大唐txt下载。 複製代碼

結語

了解 react 生命周期和更新機製確實有利於編寫代碼|||重庆城投集团董事长,特別是當代碼量越來越大時||-蓝色冰晶瘦身霜,錯用的 setState 或生命周期鉤子都可能埋下越來越多的雷|_诗兰百丽,直到有一天無法維護--|诺基亚6700s刷机。_仲博彩票怎么注册账号。||永盛国际骗局。

我的個人建議如下_|易网彩票靠谱吗:

  • 把副作用代碼通通放在 commit 階段_008彩票论坛II,因為這個階段不會影響頁麵渲染性能
  • 盡可能不要使用 forceUpdate() 方法_-|1288彩票骗局,借用 Evan You 的一句話|_|360彩票网导航走势官网,如果你發現你自己需要在 Vue 中做一次強製更新-|亿博彩票有人输钱吗,99.9% 的情況-_栾海燕,是你在某個地方做錯了事
  • 隻要調用了 setState() 就會進行 render()-|234彩票安全吗,無論 state 是否改變
  • 知道 setState() 更新的什麼時候是同步的|-三棱锥性质,什麼時候是異步的-_|掌信彩可靠吗,參見上文
  • 不要把 getDerivedStateFromProps() 當成是 UNSAFE_componentWillReceiveProps() 的替代品_欧瑞珂诗,因為 getDerivedStateFromProps() 會在每次 render() 之前執行_||易彩快3是真的吗,即使 props 沒有改變




藍藍設計www.jwrumpff.com )是一家專注而深入的界麵設計公司||粤dk0213,為期望卓越的國內外企業提供卓越的UI界麵設計|陈丽阳、BS界麵設計 __|五个人火了、 cs界麵設計 ___巴南区公租房、 ipad界麵設計 ||_成都市承包商、 包裝設計 -18号彩票225599com、 圖標定製 _||考好老师让你做一次H、 用戶體驗 |_|优博彩票网站、交互設計|__美派雅集、 網站建設 ||永盛国际彩票骗局、平麵設計服務_-郑小爽822。

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


訂閱Rss