精品国产午夜肉伦伦影院_亚洲精品国产成人_亚洲AV无码成人精品区在线播放_日韩欧美中文在线_精99久中文字幕人妻

首頁 >資訊 >

當(dāng)前快訊:React筆記-生命周期(七)

時間:2023-05-15 09:40:24     來源: 博客園
React筆記-生命周期(七)

生命周期值React組件從裝載到卸載的全過程 在這個過程中React提供了多個內(nèi)置函數(shù)供開發(fā)者在不同階段執(zhí)行需要的邏輯

狀態(tài)組件由3個階段組成 掛載階段(MOUNTING) 更新階段(UPDATING) 卸載階段(UNMOUNT)

從縱向劃分為2個階段 Render階段 Commit階段


【資料圖】

Render階段 純凈且無副作用 會被React暫停 終止 重新啟動

Commit階段 可以使用DOM 有副作用

掛載階段constructor

構(gòu)造函數(shù)(這個并不是react生命周期)

觸發(fā)時機(jī)

在組件初始化時觸發(fā)一次

構(gòu)造函數(shù)因?yàn)樵诮M件初始化時觸發(fā) 所以是初始化state最佳位置

static getDerivedStateFromProps

觸發(fā)時機(jī)

組件實(shí)例化后 重新渲染前

因此父組件更新 props變化 state更新 都會調(diào)用該函數(shù)

/**   *   * @param {*} nextProps 當(dāng)前的props   * @param {*} prevState 修改前的state   * 該生命周期函數(shù)必須有返回值   * 它需要返回一個對象來更新 State   */static getDerivedStateFromProps(nextProps, prevState) {    if (nextProps.num) {      return {        ...prevState,        num: nextProps.num * 2      }    }    return prevState;  }

注意:

該生命周期函數(shù)是一個靜態(tài)函數(shù) 所以函數(shù)內(nèi)無法訪問指向當(dāng)前實(shí)例對象的this該生命周期函數(shù)被設(shè)計(jì)成靜態(tài)方法的目的是為了保持該方法的純粹 能夠起到限制開發(fā)者訪問 this 也就是實(shí)例的作用 這樣就不能在里面調(diào)用實(shí)例方法或者 setState 以破壞該生命周期函數(shù)的功能原本該生命周期函數(shù)是被設(shè)計(jì)成 初始化、父組件更新 和 接收到 Props 才會觸發(fā),現(xiàn)在只要渲染就會觸發(fā),也就是 初始化 和 更新階段 都會觸發(fā)componentWillMount

(此生命周期函數(shù)在React v17被正式廢棄)

觸發(fā)時機(jī)

在構(gòu)造函數(shù)和裝載組件(將 DOM 樹渲染到瀏覽器中)之間觸發(fā)

注意

在此生命周期函數(shù)里使用 setState 同步設(shè)置組件內(nèi)部狀態(tài) state 將不會觸發(fā)重新渲染避免在該方法中引入任何的副作用(Effects)或訂閱(Subscription)。對于這些使用場景,建議提前到構(gòu)造函數(shù)中
render(mounting階段)

渲染函數(shù)(這個并不是react生命周期)

作用: 僅用于渲染的純函數(shù) 返回值取決于state和props(并不是真實(shí)渲染 返回的是一個JSX描述文件 真實(shí)渲染取決于所有組件渲染函數(shù)后)

注意

不能在函數(shù)中任何修改 state、props、請求數(shù)據(jù)等具有副作用的操作不能讀寫 DOM 信息不能和瀏覽器進(jìn)行交互(例如 setTimeout)
componentDidMount

觸發(fā)時機(jī)

組件完全掛載后(插入DOM樹中)立即調(diào)用 后面不會再次執(zhí)行這個函數(shù)

使用場景

渲染DOM記載數(shù)據(jù)網(wǎng)絡(luò)請求

為什么在這個階段進(jìn)行網(wǎng)絡(luò)請求

componentDidMount 這個階段已經(jīng)完成了 render,commit 階段狀態(tài)已經(jīng)穩(wěn)定,在這個階段更新狀態(tài)(state)不會造成沖突

實(shí)現(xiàn)思路

在 contructor 函數(shù)中 通過 Promise 來進(jìn)行數(shù)據(jù)的請求 并且綁定到當(dāng)前實(shí)例對象上 然后在 componentDidMount 中執(zhí)行 Promise 把數(shù)據(jù)更新到 state 上

class Life extends React.component {  componentDidMount () {  }}
更新階段componentWillReceiveProps

此生命周期函數(shù)將在React v17正式廢棄 推薦使用 static getDerivedStateFromProps()代替

觸發(fā)時機(jī)

父組件的渲染函數(shù)被調(diào)用 不論props是否改變 在渲染函數(shù)中被渲染的子組件都會經(jīng)歷更新階段并觸發(fā)該生命周期函數(shù)state更新不會觸發(fā)該函數(shù)
/* nextProps 當(dāng)前的props*/componentWillReceiveProps(nextProps) {   }
shouldComponentUpdate

目前官方已經(jīng)提供React.PureComponent 用來替代React.Component替代手寫這個方法(不需要開發(fā)者自己實(shí)現(xiàn)shouldComponentUpdate,就可以進(jìn)行簡單的判斷來提升性能)

觸發(fā)時機(jī)

因?yàn)?state 和 props 變化而更新時 在重新渲染前該生命周期函數(shù)都會觸發(fā)

使用場景

/**   *    * @param {*} nextProps 當(dāng)前的props   * @param {*} nextState 當(dāng)前的state   * @returns      根據(jù)邏輯判斷返回 true 表示繼續(xù)進(jìn)行組件渲染,否則將停止組件渲染過程。默認(rèn)返回 true,也就是說,只要組件觸發(fā)了更新,組件就一定會更新   */  shouldComponentUpdate (nextProps, nextState) {    return true  }
React.PureComponent純組件

這個是用于繼承 并不是生命周期(不需要開發(fā)者自己實(shí)現(xiàn)shouldComponentUpdate,就可以進(jìn)行簡單的判斷來提升性能)

和React.Component相比 采用了props和state淺對比來實(shí)現(xiàn)shouldComponentUpdate 其他完全相同

存在問題(為什么PureComponent比較復(fù)雜的數(shù)據(jù)結(jié)構(gòu),可能會因深層的數(shù)據(jù)不一致而產(chǎn)生錯誤的否定判斷)

這個方法只對state和props進(jìn)行了新舊地址值比較 而沒有深層對比其屬性的變化 修改地址值屬性不會導(dǎo)致頁面更新(JavaScript 中的對象一般是可變的(Mutable)因?yàn)槭褂昧艘觅x值 新的對象簡單的引用了原始對象 改變新的對象將影響到原始對象)

解決方法

避免修改原地址的屬性 采用新對象參數(shù)更新(使用 shallowCopy(淺拷貝)或 deepCopy(深拷貝)來避免被修改) 但這樣做造成了CPU和內(nèi)存的浪費(fèi)

componentWillUpdate

此生命周期函數(shù)將在React v17正式廢棄 使用componentWillReceiveProps代替

觸發(fā)時機(jī)

更新生命周期中重新渲染之前的最后一個方法 此時已經(jīng)擁有了更新后的屬性和狀態(tài) 并且可以在這個方法中隨意處理這些數(shù)據(jù)

注意

此函數(shù)不會在初始化渲染時候被觸發(fā)禁止在這個函數(shù)中調(diào)用setState方法 會造成死循環(huán)
render(updating階段)

渲染函數(shù) 與mounting階段的render一致 用于渲染被React處理過的JSX到瀏覽器

getSnapshotBeforeUpdate

觸發(fā)時機(jī)

render渲染函數(shù)之前 state已更新

使用場景

獲取render之前的dom狀態(tài)

/**   *    * @param {*} prevProps 更新前的props   * @param {*} prevState 更新前的state   * @returns 返回值可以在componentDidUpdate中接收   */  getSnapshotBeforeUpdate (prevProps, prevState) {    return null  }
componentDidUpdate

觸發(fā)時機(jī)

組件每次重新渲染后觸發(fā) 不會在初始化渲染的時候觸發(fā)

注意

在此生命周期函數(shù)中使用setState 需要加if條件判斷 prevProps、prevState 和 this.state 之間的數(shù)據(jù)變化 用于跳出循環(huán)

/**   *    * @param {*} prevProps 更新前的props   * @param {*} prevState 更新前的state   * @param {*} snapshot getSnapshotBeforeUpdate傳過來的   */  componentDidUpdate (prevProps, prevState, snapshot) {  }
react v17刪除以下生命周期函數(shù)原因

componentWillReceiveProps | componentWillUpdate | componentWillReceiveProps

原因

被廢棄的三個函數(shù)都是在render之前,因?yàn)閒iber的出現(xiàn),很可能因?yàn)楦邇?yōu)先級任務(wù)的出現(xiàn)而打斷現(xiàn)有任務(wù)導(dǎo)致它們會被執(zhí)行多次

簡而言之就是React官方認(rèn)為開發(fā)者會在這三個函數(shù)階段編寫副作用代碼(約束開發(fā)者)

卸載階段componentWillUnmount

觸發(fā)時機(jī)

在組件卸載之前觸發(fā)

使用場景

注銷事件監(jiān)聽器取消網(wǎng)絡(luò)請求取消定時器解綁 DOM 事件
componentWillUnmount () {  }
捕獲錯誤static getDerivedStateFromError

觸發(fā)時機(jī)

該生命周期函數(shù)會在子孫組件拋出錯誤時執(zhí)行

import React from "react";export default class GetDerivedStateFromError extends React.Component {    /**   *    * @param {*} error 錯誤信息   * @returns    * 它接收拋出的錯誤作為參數(shù)并且需要返回值用于更新 State   */  static getDerivedStateFromError(error) {    return   }  render () {    return (      
1
) }}
componentDidCatch

觸發(fā)時機(jī)

該生命周期函數(shù)會在子孫組件拋出錯誤時執(zhí)行

使用方式和getDerivedStateFromError一致

錯誤邊界(Error Boundary)

一般情況下 任何組件在渲染期間發(fā)生錯誤 都會導(dǎo)致整個組件樹都被卸載

錯誤邊界是React的一個組件 這個組件可以捕獲發(fā)生在任何組件樹內(nèi)錯誤 根據(jù)不同崩潰內(nèi)容用頁面反饋

注意

錯誤邊界自身錯誤異步錯誤事件中錯誤服務(wù)器渲染錯誤
import React, { Component } from "react";export default class ErrorBoundary extends Component {  state = { hasError: false };  render() {    // 發(fā)生錯誤時 hasError 為 false 用頁面反饋    if (this.state.hasError) {      return 

發(fā)生錯誤

; } // 沒有發(fā)生錯誤 hasError 為 true 正常執(zhí)行代碼 return this.props.children; } // componentDidCatch生命周期函數(shù)會在子孫組件拋出錯誤時執(zhí)行 componentDidCatch(error, info) { this.setState({ hasError: true }); }}

標(biāo)簽:

頭條精選