[React] 生命周期詳解

React 的生命周期本質(zhì)上就是一系列的鉤子函數(shù),可以分為 3 個(gè)時(shí)期:掛載佣耐、更新和卸載铲球。React 16 還新增錯(cuò)誤處理的鉤子函數(shù)。要掌握 React晰赞,生命周期是必不可少的一部分。
注意:本文只對(duì)目前最新的 React 生命周期展開(kāi)詳解(v16.4.0)选侨。

生命周期流程圖

組件創(chuàng)建時(shí)的生命周期

static getDerivedStateFromProps(nextProps, prevState)

該周期函數(shù)接收兩個(gè)參數(shù)掖鱼,新的屬性作為第一個(gè)參數(shù),先前的狀態(tài)作為第二個(gè)參數(shù)援制。當(dāng)函數(shù)返回 null 時(shí)戏挡,代表新的屬性不需要更新?tīng)顟B(tài);當(dāng)函數(shù)返回了一個(gè)對(duì)象晨仑,對(duì)象中的屬性則會(huì)被更新到 State 中褐墅。如下:

static getDerivedStateFromProps(nextProps, prevState) {
    if (prevState.currentId 拆檬!== nextProps.itemId) {
        return {
            currentId: nextProps.itemId
        };
    }
    return null;
}

上圖意思是,當(dāng)新屬性中的 itemId 與當(dāng)前 State 的 currentId 不一致時(shí)妥凳,則執(zhí)行 currentId 狀態(tài)的更新竟贯,否則返回 null,不執(zhí)行任何的更新逝钥。
簡(jiǎn)單來(lái)說(shuō)屑那,如果你的組件中,接收新的屬性不需要觸發(fā)狀態(tài)的更新艘款,可以忽略該函數(shù)持际,或在該函數(shù)中直接返回 null。
值得一提的是哗咆,該周期函數(shù)getDerivedStateFromProps(){...}是一個(gè)靜態(tài)函數(shù)蜘欲,無(wú)法訪問(wèn)組件的實(shí)例 this,所以在該函數(shù)中沒(méi)辦法訪問(wèn) this.props 和 this.state晌柬。

componentDidMount

該函數(shù)代表組件實(shí)例化完成姥份,這個(gè)時(shí)候非常適合執(zhí)行

  • 網(wǎng)絡(luò)請(qǐng)求(Ajax)
  • 事件訂閱

組件更新時(shí)的生命周期

static getDerivedStateFromProps

該周期函數(shù)在組件的屬性和狀態(tài)更新時(shí)都會(huì)被觸發(fā),用法等同組件創(chuàng)建時(shí)的 getDerivedStateFromProps 函數(shù)空繁。

shouldComponentUpdate(nextPorps, nextState)

該函數(shù)接收新的屬性作為第一個(gè)參數(shù)殿衰,新的狀態(tài)作為第二個(gè)參數(shù)。當(dāng)函數(shù)返回 true 的時(shí)候盛泡,周期函數(shù)會(huì)繼續(xù)往下執(zhí)行 render 渲染闷祥;當(dāng)函數(shù)返回 false,周期函數(shù)則會(huì)中止于此傲诵,并停止下面的渲染凯砍。如果不設(shè)置,這個(gè)函數(shù)會(huì)默認(rèn)返回 true拴竹。
利用好這個(gè)周期函數(shù)的特性悟衩,我們可以避免無(wú)用的渲染,提升頁(yè)面的性能栓拜。

getSnapshotBeforeUpdate(prevProps, prevState)

該周期函數(shù)的時(shí)期處在 render 函數(shù)執(zhí)行之后和組件 DOM 渲染之前座泳。它讓你的組件能在當(dāng)前的值可能要改變前獲得它們。該函數(shù)返回的任何值將作為 componentDidUpdate 周期函數(shù)的第三個(gè)參數(shù)幕与。

componentDidUpdate(prevProps, prevState, snapshot)

componentDidUpdate 函數(shù)會(huì)在更新發(fā)生后立即被調(diào)用挑势。
我們可以在該方法中修改組件的狀態(tài)以進(jìn)行 DOM 的更新。同時(shí)啦鸣,這也是一個(gè)適合發(fā)送網(wǎng)絡(luò)請(qǐng)求(Ajax)的地方潮饱,我們可以通過(guò)對(duì)比當(dāng)前屬性和舊屬性來(lái)判斷是否需要發(fā)送網(wǎng)絡(luò)請(qǐng)求。

組件掛載時(shí)的生命周期

componentWillUnmount

componentWillUnmount 函數(shù)在組件被卸載和銷毀之前被調(diào)用诫给。我們可以在該方法里做清理工作香拉,例如解綁定時(shí)器啦扬,取消網(wǎng)絡(luò)請(qǐng)求,清理任何在 componentDidMount 環(huán)節(jié)創(chuàng)建的 DOM 元素凫碌,取消事件訂閱扑毡。

異常處理的周期函數(shù)

componentDidCatch

錯(cuò)誤邊界是一個(gè) React 組件。錯(cuò)誤邊界組件捕捉發(fā)生在子組件樹(shù)中任意地方的 JavaScript 錯(cuò)誤证鸥,打印錯(cuò)誤日志僚楞,并且顯示回退的用戶界面。錯(cuò)誤邊界可以捕捉組件渲染期間枉层、生命周期方法中和子組件構(gòu)造函數(shù)中的錯(cuò)誤泉褐。

如果定義了這一生命周期方法,一個(gè)類組件將成為一個(gè)錯(cuò)誤邊界組件鸟蜡。我們可以在錯(cuò)誤邊界組件捕獲到 JavaScript 錯(cuò)誤的時(shí)候膜赃,顯示回退的用戶界面。

以下是一個(gè)錯(cuò)誤邊界組件

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    // 顯示錯(cuò)誤發(fā)生的回退視圖
    this.setState({ hasError: true });
    // 也可以上報(bào)錯(cuò)誤到服務(wù)器
    logErrorToMyService(error, info);
  }

  render() {
    if (this.state.hasError) {
      // 定制任意的回退視圖
      return <h1>頁(yè)面被外星人偷走了</h1>;
    }
    return this.props.children;
  }
}

然后將它作為常規(guī)組件

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>

該 componentDidCatch 方法的工作方式類似于 JavaScript catch {} 塊揉忘,但它一個(gè)適用于組件的 catch 塊跳座。實(shí)際上,大多數(shù)情況下泣矛,我們只需要聲明一次錯(cuò)誤邊界組件疲眷,并在整個(gè)應(yīng)用程序中使用它。
請(qǐng)注意您朽,錯(cuò)誤邊界僅捕獲組件樹(shù)中處于它們子層級(jí)組件中的錯(cuò)誤狂丝,錯(cuò)誤邊界本身的錯(cuò)誤無(wú)法捕獲。如果錯(cuò)誤邊界組件自身報(bào)錯(cuò)哗总,則錯(cuò)誤將傳播到其上方最接近的錯(cuò)誤邊界几颜。

參考:新版React生命周期圖

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市讯屈,隨后出現(xiàn)的幾起案子蛋哭,更是在濱河造成了極大的恐慌,老刑警劉巖涮母,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谆趾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡叛本,警方通過(guò)查閱死者的電腦和手機(jī)沪蓬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)炮赦,“玉大人,你說(shuō)我怎么就攤上這事样勃》涂保” “怎么了性芬?”我有些...
    開(kāi)封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)剧防。 經(jīng)常有香客問(wèn)我植锉,道長(zhǎng),這世上最難降的妖魔是什么峭拘? 我笑而不...
    開(kāi)封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任俊庇,我火速辦了婚禮,結(jié)果婚禮上鸡挠,老公的妹妹穿的比我還像新娘辉饱。我一直安慰自己,他們只是感情好拣展,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布彭沼。 她就那樣靜靜地躺著,像睡著了一般备埃。 火紅的嫁衣襯著肌膚如雪姓惑。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天按脚,我揣著相機(jī)與錄音于毙,去河邊找鬼。 笑死辅搬,一個(gè)胖子當(dāng)著我的面吹牛唯沮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播伞辛,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼烂翰,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蚤氏?” 一聲冷哼從身側(cè)響起甘耿,我...
    開(kāi)封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎竿滨,沒(méi)想到半個(gè)月后佳恬,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡于游,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年毁葱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贰剥。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡倾剿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情前痘,我是刑警寧澤凛捏,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站芹缔,受9級(jí)特大地震影響坯癣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜最欠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一示罗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芝硬,春花似錦蚜点、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至皮官,卻和暖如春脯倒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捺氢。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工藻丢, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人摄乒。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓悠反,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親馍佑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子斋否,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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

  • React 生命周期詳解 生命周期的三個(gè)階段 裝載過(guò)程: Mouth React組件的第一次渲染DOM的過(guò)程, 更...
    前端河豚閱讀 731評(píng)論 0 0
  • 1 React生命周期流程 調(diào)用流程可以參看上圖拭荤。分為實(shí)例化茵臭,存在期和銷毀三個(gè)不同階段。介紹生命周期流程的文章很多...
    Dabao123閱讀 322評(píng)論 0 1
  • Each component has several "lifecycle methods" that you c...
    暮落晨曦閱讀 475評(píng)論 0 0
  • 組件生命周期,組件本質(zhì)上是狀態(tài)機(jī) 組件把狀態(tài)和結(jié)果一一對(duì)應(yīng)起來(lái) 組件中有state狀態(tài) 和 props屬性雏亚,屬性是...
    mannysys閱讀 393評(píng)論 0 0
  • 這一部分內(nèi)容一直一知半解缨硝,最近發(fā)現(xiàn)一篇文章,非常好的解釋了生命周期的問(wèn)題罢低,留存在這里查辩,以備后查! 簡(jiǎn)介 一個(gè)rea...
    春木橙云閱讀 920評(píng)論 0 5