React新生命周期

首先,React生命周期分為三個(gè)階段:掛載、渲染和卸載。由三種不同的形式組成:render渲染、props改變和state改變。由兩種過(guò)程組成:掛載卸載過(guò)程、更新過(guò)程。

下面是React16.x版本之前的生命周期

舊生命周期

16.x之前的生命周期

1.掛載卸載過(guò)程

1.1.constructor()

當(dāng)組件被實(shí)例化之后,即使不手寫構(gòu)造函數(shù),react會(huì)自動(dòng)創(chuàng)建并執(zhí)行構(gòu)造函數(shù),并且構(gòu)造函數(shù)是最先執(zhí)行的。如果手寫了構(gòu)造函數(shù),就必須手動(dòng)調(diào)用父類的構(gòu)造函數(shù)來(lái)實(shí)例化子類,否則會(huì)導(dǎo)致this指向錯(cuò)誤。手寫構(gòu)造函數(shù)的目的就是為了給父類也就是this添加屬性,即使不添加任何屬性,react也會(huì)自動(dòng)創(chuàng)建state,只不過(guò)此時(shí)的state為null

1.2.componentWillMount()

此生命周期函數(shù)代表組件已經(jīng)經(jīng)歷了constructor()初始化數(shù)據(jù)之后,但是組件未掛載,也就是還未渲染DOM 的時(shí)候。

1.3.componentDidMount()

此生命周期函數(shù)代表組件已經(jīng)被掛載完成,DOM節(jié)點(diǎn)已經(jīng)渲染完成,可以在此階段請(qǐng)求數(shù)據(jù)接口,返回?cái)?shù)據(jù)之后會(huì)重新將數(shù)據(jù)渲染到組件中

1.4.componentWillUnmount ()

此過(guò)程完成組件的卸載與數(shù)據(jù)的銷毀

2.更新過(guò)程

2.1.componentWillReceiveProps (nextProps)

父組件中改變了props傳值時(shí)觸發(fā)的函數(shù), 但是此函數(shù)觸發(fā)有條件: 一、組件初次加載時(shí)不調(diào)用此函數(shù) 二、當(dāng)組件接受了新的props時(shí)才調(diào)用此函數(shù) 三、當(dāng)父組件進(jìn)行更新以及父組件重新render(不管父組件的狀態(tài)有沒有改變)被調(diào)用后執(zhí)行

2.2.shouldComponentUpdate(nextProps,nextState)

此函數(shù)表示組件接收到新的props或者state時(shí)調(diào)用,需要注意的是,初次渲染此函數(shù)不會(huì)執(zhí)行。并且此函數(shù)返回bool值,返回值為true時(shí),就會(huì)更新dom(使用diff算法更新),當(dāng)返回值為false時(shí)就會(huì)阻止更新

此生命周期函數(shù)可以起到性能優(yōu)化的作用,因?yàn)閞eact父組件的重新渲染會(huì)導(dǎo)致其所有子組件的重新渲染,這個(gè)時(shí)候其實(shí)我們是不需要所有子組件都跟著重新渲染的,因此需要在子組件的該生命周期中做判斷

2.3.componentWillUpdate (nextProps,nextState)

此函數(shù)表示組件加載時(shí)不調(diào)用,只有在組件將要更新時(shí)才調(diào)用,此時(shí)可以修改state

2.4.render()

react最重要的步驟,創(chuàng)建虛擬dom,進(jìn)行diff算法,更新dom樹都在此進(jìn)行

2.5.componentDidUpdate(prevProps,prevState)

此函數(shù)表示組件數(shù)據(jù)更新已經(jīng)完成,但是組件加載時(shí)不調(diào)用,組件更新完成后調(diào)用,需要注意的是此函數(shù)在render后執(zhí)行

新生命周期

  • React生命周期新引入了兩個(gè)生命周期函數(shù):getDerivedStateFromPropsgetSnapShotBeforeUpdate,代替在17.x版本中會(huì)廢棄的生命周期方法:componentWillMount()componentWillReceiveProps()componentWillUpdate()。16.x中新增UNSAFE前綴為別名的三個(gè)函數(shù)UNSAFE_componentWillMount()UNSAFE_componentWillReceiveProps()UNSAFE_componentWillUpdate(),并在17.x版本中會(huì)保留 UNSAFE前綴為別名的三個(gè)函數(shù)

  • getDerivedStateFromProps()無(wú)論是Mounting還是Updating,也無(wú)論是因?yàn)槭裁匆鸬腢pdating,全部都會(huì)被調(diào)用

  • getSnapshotBeforeUpdate()被調(diào)用于render之后,可以讀取但無(wú)法使用DOM的時(shí)候。它使您的組件可以在可能更改之前從DOM捕獲一些信息(例如滾動(dòng)位置)。此生命周期返回的任何值都將作為參數(shù)傳遞給componentDidUpdate()

結(jié)合實(shí)例可以更直觀的理解react新生命周期

import React, { Component } from 'react'

export default class NewReactComponent extends Component {
    constructor(props) {
        super(props)
        // getDefaultProps:接收初始props
        // getInitialState:初始化state
        // 當(dāng)組件被實(shí)例化之后,即使不手寫構(gòu)造函數(shù),react會(huì)自動(dòng)創(chuàng)建并執(zhí)行構(gòu)造函數(shù),并且構(gòu)造函數(shù)是最先執(zhí)行的
        // 如果手寫了構(gòu)造函數(shù),就必須手動(dòng)調(diào)用父類的構(gòu)造函數(shù)來(lái)實(shí)例化子類,否則會(huì)導(dǎo)致this指向錯(cuò)誤
        // 手寫構(gòu)造函數(shù)的目的就是為了給父類也就是this添加屬性,即使不添加任何屬性,react也會(huì)自動(dòng)創(chuàng)建state,只不過(guò)此時(shí)的state為null
    }
    state = {
        age:18
    }
    static getDerivedStateFromProps=(props, state)=> {
        // 組件掛載必須要經(jīng)歷的生命周期
        // 組件每次被rerender的時(shí)候,包括在組件構(gòu)建之后(虛擬dom之后,實(shí)際dom掛載之前),每次獲取新的props或state之后;
        // 每次接收新的props之后都會(huì)返回一個(gè)對(duì)象作為新的state,返回null則說(shuō)明不需要更新state
        // 此函數(shù)是一個(gè)靜態(tài)函數(shù),所以函數(shù)體內(nèi)不能訪問(wèn)this,輸出完全由輸入決定
        console.log('static getDerivedStateFromProps(props, state)')
        console.log(props)
        console.log(state)
        return state
    }
    componentDidCatch(error, info) {
        // 獲取到j(luò)avascript錯(cuò)誤

    }
    changeState=()=>{
        this.setState({
            age:22
        })
    }
    render() {
        const {age} = this.state
        const {name} = this.props
        return (
            <>
                <h4>新生命周期</h4>
                <p>props值:name:{name},age:{age}</p>
                <button onClick={this.changeState}>change state</button>
            </>
        )
    }
    componentDidMount() { 
        // 掛載后調(diào)用且只調(diào)用一次
        console.log('componentDidMount')
    }

    shouldComponentUpdate(nextProps, nextState) {
        // nextProps和nextProps的含義就是字面量的含義,代表更新之后的狀態(tài)
        // 組件Props或者state改變時(shí)觸發(fā),true:更新,false:不更新
        console.log('shouldComponentUpdate')
        console.log(nextProps)
        console.log(nextState)
        return true
    }
    getSnapshotBeforeUpdate(prevProps, prevState) {
        // 組件更新前觸發(fā)
        // 調(diào)用順序與這個(gè)例子的順序是一樣的
        console.log('getSnapshotBeforeUpdate')
        return 'ok'
    }
    componentDidUpdate() {
        // 組件更新后觸發(fā)
        console.log('componentDidUpdate')
    }

    componentWillUnmount() {
        // 組件卸載時(shí)觸發(fā)

    }
}

掛載

當(dāng)組件實(shí)例被創(chuàng)建并插入 DOM 中時(shí),其生命周期調(diào)用順序如下:

更新

當(dāng)組件的 props 或 state 發(fā)生變化時(shí)會(huì)觸發(fā)更新。組件更新的生命周期調(diào)用順序如下:

卸載

當(dāng)組件從 DOM 中移除時(shí)會(huì)調(diào)用如下方法:

錯(cuò)誤處理

當(dāng)渲染過(guò)程,生命周期,或子組件的構(gòu)造函數(shù)中拋出錯(cuò)誤時(shí),會(huì)調(diào)用如下方法:

參考資料:
https://react.docschina.org/docs/react-component.html#static-getderivedstatefromerror
https://segmentfault.com/a/1190000016617400?utm_source=tag-newest

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。