React 16 生命周期函數(shù)淺析

前言

剛學(xué)React的時(shí)候才 React16.1 剛出來每多久胎源,那時(shí)候剛出來一個(gè)的鉤子函數(shù) componentDidCatch,可應(yīng)用于處理錯(cuò)誤邊界跟磨。但 React v16.3 又新增了兩個(gè)生命周期函數(shù)逃糟,前面寫的那篇總結(jié)好像有點(diǎn)過時(shí)笆焰,因此又總結(jié)了一下,做個(gè)補(bǔ)充氢妈。

一粹污、變動(dòng)情況

React v16.3 發(fā)布時(shí)除了全新的 context API 之外,還引入了兩個(gè)新的生命周期函數(shù):

  • getDerivedStateFromProps
  • getSnapshotBeforeUpdate

并且也確定了在v17.0版本將移除三個(gè)生命周期函數(shù):

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate首量。

總的來說就是移除了所有帶 will 的生命周期函數(shù)壮吩,也就是 render 之前的生命周期函數(shù)除了shouldUpdateComponent 之外的生命周期函數(shù)都被干掉了。

二加缘、變動(dòng)詳情

以我的理解鸭叙,React 生命周期的變動(dòng)主要是為了兩方面:

  1. 迎合 Fiber 架構(gòu)變動(dòng)的需求
  2. 規(guī)范開發(fā)者開發(fā)的行為

2.1 getDerivedStateFromProps

首先以前需要利用被刪除的那些生命周期函數(shù)才能實(shí)現(xiàn)的功能,都可以通過 getDerivedStateProps 的幫助來實(shí)現(xiàn)拣宏。
那 getDerivedStateProps 究竟是啥東西呢沈贝?首先 getDerivedStateProps 生命周期函數(shù)是一個(gè)靜態(tài)函數(shù),所以函數(shù)體內(nèi)不能訪問this勋乾。

static getDerivedStateFromProps(nextProps, prevState) {
  if (nextProps.translateX !== prevState.translateX) {
    return {
      translateX: nextProps.translateX,
    };
  }
  return null;
}

這樣的函數(shù)其實(shí)表達(dá)的意思很明確宋下,我們?cè)谶@個(gè)函數(shù)內(nèi)部就好好的做個(gè)運(yùn)算就行了嗡善,其他的騷操作就別再這做了。

比如很多開發(fā)者很喜歡在 componentWillMount 進(jìn)行AJAX請(qǐng)求以獲取數(shù)據(jù)学歧,因?yàn)樗麄冋J(rèn)為 componentWillMount在render 之前執(zhí)行罩引,早一點(diǎn)執(zhí)行就早得到結(jié)果。但其實(shí)在 componentWillMount 中發(fā)起 AJAX 請(qǐng)求枝笨,不管多快得到結(jié)果袁铐,都趕不上首次 render 的速度,因此這種操作和可能會(huì)導(dǎo)致首屏無數(shù)據(jù)而導(dǎo)致白屏横浑。

另外對(duì)于 React16 架構(gòu)最大的變動(dòng)就是 Fiber 了昭躺,在 Fiber 架構(gòu)下啟用了啟用 async render 之后,render 之前的生命周期函數(shù)可能會(huì)被調(diào)用多次伪嫁,如果在 componentWillMount 進(jìn)行 AJAX 請(qǐng)求可能會(huì)導(dǎo)致無謂地多次調(diào)用AJAX领炫。

其次在 React v16.3 剛發(fā)布這個(gè)函數(shù)的時(shí)候,getDerivedStateFromProps 這個(gè)生命周期函數(shù)张咳,我在從它的名字來看的時(shí)候帝洪,還以為它主要是為了代替 componentWillReceiveProps 的,但進(jìn)過了解后發(fā)現(xiàn)脚猾,這樣說其實(shí)并不準(zhǔn)確葱峡。因?yàn)?componentWillReceiveProps 只在因?yàn)楦附M件而引發(fā)的Updating過程中才會(huì)被調(diào)用。而getDerivedStateFromProps在Updating和Mounting過程中都會(huì)被調(diào)用龙助。還需要注意的是砰奕,同樣是 Updating 過程,如果是因?yàn)樽陨磉M(jìn)行的 setState 或者 forceUpdate 所引發(fā)的渲染提鸟,getDerivedStateFromProps 也不會(huì)被調(diào)用军援。

這很容易引發(fā)一些問題,且讓人難以理解這種差異称勋,畢竟竟然可以在 updating 和 Mounting 過程中都可以調(diào)用胸哥,那么為什么在 setState 和 forceUpdate 發(fā)生時(shí)不會(huì)調(diào)用呢?且如果這樣的話赡鲜,那么在平時(shí)使用這個(gè)生命周期函數(shù)的時(shí)候空厌,需不需要單獨(dú)考慮不調(diào)用這個(gè)函數(shù)的時(shí)候需要怎么進(jìn)行處理,諸如此類的問題還有不少银酬。

也這是由于這個(gè)原因嘲更,React 團(tuán)隊(duì)很快就做出了調(diào)整,改正了這一點(diǎn)揩瞪,讓 getDerivedStateFromProps 無論是 Mounting 還是 Updating 還是自身組件的 setstate 或 forceUpdate 都會(huì)調(diào)用這個(gè)函數(shù)赋朦。這明顯到簡(jiǎn)單多了,非常好理解:只要進(jìn)行掛載或更新組件,都會(huì)調(diào)用 getDerivedStateFromProps 生命周期函數(shù)北发。

2.2 getSnapshotBeforeUpdate

除了 getDerivedStateFromProps 外纹因,React v16.3還引入了一個(gè)新的聲明周期函數(shù)getSnapshotBeforeUpdate。這函數(shù)會(huì)在render之后執(zhí)行琳拨,而執(zhí)行之時(shí)DOM元素還沒有被更新瞭恰,給了一個(gè)機(jī)會(huì)去獲取DOM信息,計(jì)算得到一個(gè)snapshot狱庇,這個(gè)snapshot會(huì)作為componentDidUpdate的第三個(gè)參數(shù)傳入惊畏。

  getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log('#enter getSnapshotBeforeUpdate');
    return 'foo';
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    console.log('#enter componentDidUpdate snapshot = ', snapshot);
  }

上面這段代碼可以看出來這個(gè)snapshot怎么個(gè)用法,snapshot咋看還以為是組件級(jí)別的某個(gè)“快照”密任,其實(shí)可以是任何值颜启,到底怎么用完全看開發(fā)者自己,getSnapshotBeforeUpdate把snapshot返回浪讳,然后DOM改變缰盏,然后snapshot傳遞給componentDidUpdate。

官方給了一個(gè)例子淹遵,用getSnapshotBeforeUpdate來處理scroll口猜,坦白說,我也想不出其他更常用更好懂的需要getSnapshotBeforeUpdate的例子透揣,這個(gè)函數(shù)應(yīng)該大部分開發(fā)者都用不上济炎。(這是看程墨大佬的說法抄的,我還是沒搞清楚這個(gè)函數(shù)有啥用辐真。须尚。。o(╥﹏╥)o)

其他

總的來說這些生命周期函數(shù)是 React 團(tuán)隊(duì)試圖通過框架級(jí)別的 API 來約束或者說幫助開發(fā)者寫出可維護(hù)性更佳的 JavaScript 代碼侍咱。以前一些影響性能的操作耐床,到現(xiàn)在React好像完全不能忍受了,逼著大家寫好的代碼放坏,這其實(shí)挺不錯(cuò)的咙咽。

而這些生命周期函數(shù)的改動(dòng)也之一要到React 17 才會(huì)進(jìn)行實(shí)裝,且那些要移除的生命周期也不會(huì)完全廢棄淤年,只需要加上UNSATE_的前綴還是可以用的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蜡豹,一起剝皮案震驚了整個(gè)濱河市麸粮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌镜廉,老刑警劉巖弄诲,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡齐遵,警方通過查閱死者的電腦和手機(jī)寂玲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梗摇,“玉大人拓哟,你說我怎么就攤上這事×媸冢” “怎么了断序?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)糜烹。 經(jīng)常有香客問我违诗,道長(zhǎng),這世上最難降的妖魔是什么疮蹦? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任诸迟,我火速辦了婚禮,結(jié)果婚禮上愕乎,老公的妹妹穿的比我還像新娘阵苇。我一直安慰自己,他們只是感情好妆毕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布慎玖。 她就那樣靜靜地躺著,像睡著了一般笛粘。 火紅的嫁衣襯著肌膚如雪趁怔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天薪前,我揣著相機(jī)與錄音润努,去河邊找鬼。 笑死示括,一個(gè)胖子當(dāng)著我的面吹牛铺浇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播垛膝,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鳍侣,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了吼拥?” 一聲冷哼從身側(cè)響起倚聚,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凿可,沒想到半個(gè)月后惑折,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年惨驶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了白热。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡粗卜,死狀恐怖屋确,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情休建,我是刑警寧澤乍恐,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站测砂,受9級(jí)特大地震影響茵烈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜砌些,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一呜投、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧存璃,春花似錦仑荐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至偎球,卻和暖如春洒扎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背衰絮。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工袍冷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人猫牡。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓胡诗,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親淌友。 傳聞我的和親對(duì)象是個(gè)殘疾皇子煌恢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容