9-React 組件之生命周期

React.js

[TOC]

生命周期

所謂的生命周期就是指某個事物從開始到結(jié)束的各個階段,當然在 <u>React.js</u> 中指的是組件從創(chuàng)建到銷毀的過程经磅,<u>React.js</u> 在這個過程中的不同階段調(diào)用的函數(shù)枕荞,通過這些函數(shù)歉井,我們可以更加精確的對組件進行控制甚疟,前面我們一直在使用的 <u>render</u> 函數(shù)其實就是組件生命周期渲染階段執(zhí)行的函數(shù)

周期分類

<u>React.js</u> 為組件的生命周期劃分了四個不同的階段

  • 掛載階段
  • 更新階段
  • 卸載階段
  • 錯誤處理

wd不同的階段又會對應著一些不同的函數(shù)

參考:http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

[圖片上傳失敗...(image-5cb90e-1614087199201)]

掛載階段

掛載階段是指組件創(chuàng)建到渲染到頁面的過程茧跋,這個過程提供了四個不同的函數(shù)

  • constructor()
  • render()
  • static getDerivedStateFromProps()
  • componentDidMount()

constructor

constructor(props)

類的構(gòu)造函數(shù)颤芬,也是組件初始化函數(shù)悲幅,一般情況下孽文,我們會在這個階段做一些初始化的工作

  • 初始化 <u>state</u>
  • 處理事件綁定函數(shù)的 <u>this</u>

render()

<u>render</u> 方法是 <u>Class</u> 組件必須實現(xiàn)的方法

static getDerivedStateFromProps()

static getDerivedStateFromProps(props, state)

該方法會在 <u>render</u> 方法之前調(diào)用,無論是掛載階段還是更新階段夺艰,它的存在只有一個目的:讓組件在 <u>props</u> 變化時更新 <u>state</u>

案例:郵件發(fā)送-收件人選擇

componentDidMount()

componentDidMount()

在組件掛載后(<u>render</u> 的內(nèi)容插入 <u>DOM</u> 樹中)調(diào)用芋哭。通常在這個階段,我們可以:

  • 操作 <u>DOM</u> 節(jié)點
  • 發(fā)送請求

更新階段

更新階段是指組件重新渲染的過程郁副,組件 <u>state</u> 的更新(調(diào)用 <u>setState()</u>)和父組件渲染都會觸發(fā)

  • static getDerivedStateFromProps()
  • shouldComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

static getDerivedStateFromProps()

同掛載階段减牺,更新階段也會觸發(fā)該生命周期函數(shù)

shouldComponentUpdate()

shouldComponentUpdate(nextProps, nextState)

發(fā)生在更新階段,<u>getDerivedStateFromProps</u> 之后存谎,<u>render</u> 之前拔疚,該函數(shù)會返回一個布爾值,決定了后續(xù)是否執(zhí)行 <u>render</u>既荚,首次渲染不會調(diào)用該函數(shù)

import React from 'react';
import Child from './Child';

export default class ShouldComponentUpdateComponent extends React.Component {
    constructor(...args) {
        super(...args);
        this.state = {
            n: 1,
        }
    }
  
    render() {
        return(
            <div>
                    <h2 onClick={e=> {
                    this.setState({n: this.state.n + 1})
                }}>n: {this.state.n}</h2>
                <Child value={this.state.n} />
              </div>
        )
    }
}
import React from 'react';

export default class Child extends React.Component {

    constructor(...props) {
        super(...props);

        this.state = {
            value: this.props.value
        };
    }
  
    shouldComponentUpdate(nextProps, nextState) {
        return this.state.value !== nextState.value;
    }
  
    render() {
        console.log('render');
        return(
            <div>
                value: {this.state.value}
                <button onClick={e=>{
                    this.setState({
                        value: this.state.value + 1
                    })
                }}>+</button>
            </div>
        );
    }
}

此方法僅作為性能優(yōu)化的方式而存在稚失,不要企圖依靠此方法來“阻止”渲染,因為可能會產(chǎn)生一些問題恰聘。其次句各,在 <u>React.js</u> 中本來對渲染已經(jīng)做了必要的優(yōu)化了,所以通過該函數(shù)本質(zhì)上不能帶來特別大的明顯提升晴叨,且容易增加組件的復雜性凿宾,變得難以維護,除非確定使用它能為當前組件帶來顯著的性能提升

官方后期也會更改該方法的特性兼蕊,即使返回 <u>false</u> 仍可能會重新渲染組件

不推薦濫用該函數(shù)

render()

同上

getSnapshotBeforeUpdate()

getSnapshotBeforeUpdate(prevProps, prevState)

該方法在 <u>render()</u> 之后初厚,但是在輸出到 <u>DOM</u> 之前執(zhí)行,用來獲取渲染之前的快照孙技。當我們想在當前一次更新前獲取上次的 <u>DOM</u> 狀態(tài)产禾,可以在這里進行處理,該函數(shù)的返回值將作為參數(shù)傳遞給下個生命周期函數(shù) <u>componentDidUpdate</u>

該函數(shù)并不常用牵啦。

componentDidUpdate()

componentDidUpdate(prevProps, prevState, snapshot)

該函數(shù)會在 <u>DOM</u> 更新后立即調(diào)用亚情,首次渲染不會調(diào)用該方法。我們可以在這個函數(shù)中對渲染后的 <u>DOM</u> 進行操作

卸載階段

當組件從 DOM 中移除時會調(diào)用如下方法

  • componentWillUnmount()

componentWillUnmount()

componentWillUnmount()

該方法會在組件卸載及銷毀前調(diào)用蕾久,我們可以在這里做一些清理工作势似,如:組件內(nèi)的定時器、未完成的請求等

錯誤處理

當渲染過程僧著,子組件的構(gòu)造函數(shù)或生命周期中拋出錯誤時履因,會調(diào)用如下方法

  • static getDerivedStateFromError()
  • componentDidCatch()

static getDerivedStateFromError()

static getDerivedStateFromError(error)

該方法用來獲取子組件拋出的錯誤,返回值是一個對象盹愚,該對象被存儲在 <u>state</u> 中栅迄,在后續(xù)的 <u>render</u> 方法中就可以根據(jù)這個對象的值來進行處理,如:顯示不同的 <u>UI</u>

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

  static getDerivedStateFromError(error) {
      return { hasError: true };
  }

  render() {
      if (this.state.hasError) {
            return <div>出錯了</div>;
      }
      return this.props.children;
  }
}

componentDidCatch()

componentDidCatch(error, info)

該方法與 <u>getDerivedStateFromError()</u> 類似皆怕,但是也有不同的地方:

  • 該方法會有一個記錄詳細錯誤堆棧信息的 <u>info</u> 參數(shù)
  • 該方法可以執(zhí)行一些額外的操作:打印錯誤毅舆、上報錯誤信息……
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末西篓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子憋活,更是在濱河造成了極大的恐慌岂津,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悦即,死亡現(xiàn)場離奇詭異吮成,居然都是意外死亡,警方通過查閱死者的電腦和手機辜梳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門粱甫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人作瞄,你說我怎么就攤上這事茶宵。” “怎么了宗挥?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵乌庶,是天一觀的道長。 經(jīng)常有香客問我属韧,道長安拟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任宵喂,我火速辦了婚禮,結(jié)果婚禮上会傲,老公的妹妹穿的比我還像新娘锅棕。我一直安慰自己,他們只是感情好淌山,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布裸燎。 她就那樣靜靜地躺著,像睡著了一般泼疑。 火紅的嫁衣襯著肌膚如雪德绿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天退渗,我揣著相機與錄音移稳,去河邊找鬼。 笑死会油,一個胖子當著我的面吹牛个粱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播翻翩,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼都许,長吁一口氣:“原來是場噩夢啊……” “哼稻薇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起胶征,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤塞椎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后睛低,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體案狠,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年暇昂,在試婚紗的時候發(fā)現(xiàn)自己被綠了莺戒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡急波,死狀恐怖从铲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情澄暮,我是刑警寧澤名段,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站泣懊,受9級特大地震影響伸辟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜馍刮,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一信夫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧卡啰,春花似錦静稻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至亡脸,卻和暖如春押搪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背浅碾。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工大州, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人及穗。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓摧茴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親埂陆。 傳聞我的和親對象是個殘疾皇子苛白,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

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