當前快訊:React筆記-生命周期(七)
掛載階段constructor生命周期值React組件從裝載到卸載的全過程 在這個過程中React提供了多個內置函數供開發者在不同階段執行需要的邏輯
狀態組件由3個階段組成 掛載階段(MOUNTING) 更新階段(UPDATING) 卸載階段(UNMOUNT)
從縱向劃分為2個階段 Render階段 Commit階段
【資料圖】
Render階段 純凈且無副作用 會被React暫停 終止 重新啟動
Commit階段 可以使用DOM 有副作用
構造函數(這個并不是react生命周期)
觸發時機
在組件初始化時觸發一次
構造函數因為在組件初始化時觸發 所以是初始化state最佳位置
static getDerivedStateFromProps觸發時機
組件實例化后 重新渲染前
因此父組件更新 props變化 state更新 都會調用該函數
/** * * @param {*} nextProps 當前的props * @param {*} prevState 修改前的state * 該生命周期函數必須有返回值 * 它需要返回一個對象來更新 State */static getDerivedStateFromProps(nextProps, prevState) { if (nextProps.num) { return { ...prevState, num: nextProps.num * 2 } } return prevState; }
注意:
該生命周期函數是一個靜態函數 所以函數內無法訪問指向當前實例對象的this該生命周期函數被設計成靜態方法的目的是為了保持該方法的純粹 能夠起到限制開發者訪問 this 也就是實例的作用 這樣就不能在里面調用實例方法或者 setState 以破壞該生命周期函數的功能原本該生命周期函數是被設計成 初始化、父組件更新 和 接收到 Props 才會觸發,現在只要渲染就會觸發,也就是 初始化 和 更新階段 都會觸發componentWillMount(此生命周期函數在React v17被正式廢棄)
render(mounting階段)觸發時機
在構造函數和裝載組件(將 DOM 樹渲染到瀏覽器中)之間觸發
注意
在此生命周期函數里使用 setState 同步設置組件內部狀態 state 將不會觸發重新渲染避免在該方法中引入任何的副作用(Effects)或訂閱(Subscription)。對于這些使用場景,建議提前到構造函數中
渲染函數(這個并不是react生命周期)
componentDidMount作用: 僅用于渲染的純函數 返回值取決于state和props(并不是真實渲染 返回的是一個JSX描述文件 真實渲染取決于所有組件渲染函數后)
注意
不能在函數中任何修改 state、props、請求數據等具有副作用的操作不能讀寫 DOM 信息不能和瀏覽器進行交互(例如 setTimeout)
觸發時機
組件完全掛載后(插入DOM樹中)立即調用 后面不會再次執行這個函數
使用場景
渲染DOM記載數據網絡請求為什么在這個階段進行網絡請求
componentDidMount 這個階段已經完成了 render,commit 階段狀態已經穩定,在這個階段更新狀態(state)不會造成沖突
實現思路
在 contructor 函數中 通過 Promise 來進行數據的請求 并且綁定到當前實例對象上 然后在 componentDidMount 中執行 Promise 把數據更新到 state 上
class Life extends React.component { componentDidMount () { }}
更新階段componentWillReceiveProps此生命周期函數將在React v17正式廢棄 推薦使用 static getDerivedStateFromProps()代替
觸發時機
父組件的渲染函數被調用 不論props是否改變 在渲染函數中被渲染的子組件都會經歷更新階段并觸發該生命周期函數state更新不會觸發該函數
/* nextProps 當前的props*/componentWillReceiveProps(nextProps) { }
shouldComponentUpdate目前官方已經提供React.PureComponent 用來替代React.Component替代手寫這個方法(不需要開發者自己實現shouldComponentUpdate,就可以進行簡單的判斷來提升性能)
觸發時機
因為 state 和 props 變化而更新時 在重新渲染前該生命周期函數都會觸發
使用場景
/** * * @param {*} nextProps 當前的props * @param {*} nextState 當前的state * @returns 根據邏輯判斷返回 true 表示繼續進行組件渲染,否則將停止組件渲染過程。默認返回 true,也就是說,只要組件觸發了更新,組件就一定會更新 */ shouldComponentUpdate (nextProps, nextState) { return true }
React.PureComponent純組件componentWillUpdate這個是用于繼承 并不是生命周期(不需要開發者自己實現shouldComponentUpdate,就可以進行簡單的判斷來提升性能)
和React.Component相比 采用了props和state淺對比來實現shouldComponentUpdate 其他完全相同
存在問題(為什么PureComponent比較復雜的數據結構,可能會因深層的數據不一致而產生錯誤的否定判斷)
這個方法只對state和props進行了新舊地址值比較 而沒有深層對比其屬性的變化 修改地址值屬性不會導致頁面更新(JavaScript 中的對象一般是可變的(Mutable)因為使用了引用賦值 新的對象簡單的引用了原始對象 改變新的對象將影響到原始對象)
解決方法
避免修改原地址的屬性 采用新對象參數更新(使用 shallowCopy(淺拷貝)或 deepCopy(深拷貝)來避免被修改) 但這樣做造成了CPU和內存的浪費
render(updating階段)此生命周期函數將在React v17正式廢棄 使用componentWillReceiveProps代替
觸發時機
更新生命周期中重新渲染之前的最后一個方法 此時已經擁有了更新后的屬性和狀態 并且可以在這個方法中隨意處理這些數據
注意
此函數不會在初始化渲染時候被觸發禁止在這個函數中調用setState方法 會造成死循環
getSnapshotBeforeUpdate渲染函數 與mounting階段的render一致 用于渲染被React處理過的JSX到瀏覽器
觸發時機
render渲染函數之前 state已更新
使用場景
獲取render之前的dom狀態
/** * * @param {*} prevProps 更新前的props * @param {*} prevState 更新前的state * @returns 返回值可以在componentDidUpdate中接收 */ getSnapshotBeforeUpdate (prevProps, prevState) { return null }
componentDidUpdate觸發時機
組件每次重新渲染后觸發 不會在初始化渲染的時候觸發
注意
在此生命周期函數中使用setState 需要加if條件判斷 prevProps、prevState 和 this.state 之間的數據變化 用于跳出循環
/** * * @param {*} prevProps 更新前的props * @param {*} prevState 更新前的state * @param {*} snapshot getSnapshotBeforeUpdate傳過來的 */ componentDidUpdate (prevProps, prevState, snapshot) { }
react v17刪除以下生命周期函數原因卸載階段componentWillUnmountcomponentWillReceiveProps | componentWillUpdate | componentWillReceiveProps
原因
被廢棄的三個函數都是在render之前,因為fiber的出現,很可能因為高優先級任務的出現而打斷現有任務導致它們會被執行多次
簡而言之就是React官方認為開發者會在這三個函數階段編寫副作用代碼(約束開發者)
觸發時機
在組件卸載之前觸發
使用場景
注銷事件監聽器取消網絡請求取消定時器解綁 DOM 事件
componentWillUnmount () { }
捕獲錯誤static getDerivedStateFromError觸發時機
該生命周期函數會在子孫組件拋出錯誤時執行
import React from "react";export default class GetDerivedStateFromError extends React.Component { /** * * @param {*} error 錯誤信息 * @returns * 它接收拋出的錯誤作為參數并且需要返回值用于更新 State */ static getDerivedStateFromError(error) { return } render () { return ( 1 ) }}
componentDidCatch錯誤邊界(Error Boundary)觸發時機
該生命周期函數會在子孫組件拋出錯誤時執行
使用方式和getDerivedStateFromError一致
一般情況下 任何組件在渲染期間發生錯誤 都會導致整個組件樹都被卸載
錯誤邊界是React的一個組件 這個組件可以捕獲發生在任何組件樹內錯誤 根據不同崩潰內容用頁面反饋
注意
錯誤邊界自身錯誤異步錯誤事件中錯誤服務器渲染錯誤
import React, { Component } from "react";export default class ErrorBoundary extends Component { state = { hasError: false }; render() { // 發生錯誤時 hasError 為 false 用頁面反饋 if (this.state.hasError) { return 發生錯誤
; } // 沒有發生錯誤 hasError 為 true 正常執行代碼 return this.props.children; } // componentDidCatch生命周期函數會在子孫組件拋出錯誤時執行 componentDidCatch(error, info) { this.setState({ hasError: true }); }}
標簽:
頭條精選
- 當前快訊:React筆記-生命周期(七)2023-05-15
- AI DevOps | ChatGPT 與研發效能、效率2023-05-15
- 劉強東很“著急”,京東變革進行時2023-05-15
- 本周A股限售股解禁市值約366億元,環比降逾2023-05-15
- 廣西壯族自治區三江侗族自治縣發布大霧黃色2023-05-15
- 廣西壯族自治區靈川縣發布大霧黃色預警_世2023-05-15
- 恩比德:綠軍聯盟最強 系列賽多數時候我們2023-05-15
- 恩比德:你可以說 近兩戰的失利削弱了76人2023-05-15
- 交行易貸通申請條件_交行易貸通2023-05-15
- 長沙南站在哪里坐地鐵_長沙南站在哪里|天天2023-05-15
- 全球速遞!硬核科技論 | 賽車同款序列式2023-05-15
- 今日觀點!探野川西 新RAV4榮放長途試駕體驗2023-05-15
- 速度與激情8演員表圖片_速度與激情8演員-當2023-05-14
- 青島會計繼續教育考試可以考幾次_青島會計2023-05-14
- 持續降價 7.18萬就能買寶來 銷量明顯穩了2023-05-14
- 通用汽車在美國召回99.5萬輛汽車:氣囊已致2023-05-14
- 環球今日報丨彎梁摩托車_彎梁125摩托車哪款2023-05-14
- 全球速讀:飛龍騎臉怎么輸黃旭東_飛龍騎臉2023-05-14
- 德昌縣氣象臺發布大風藍色預警信號【IV級/2023-05-14
- 熱?熱?熱?!成都下周直沖35℃!-世界新動態2023-05-14
- 涼皮的調料汁怎么調配_好吃的陜西涼皮調料2023-05-14
- 當前熱文:月餅怎么做的方法教程簡單_中秋2023-05-14
- 焦點熱門:看一個男人,是不是真正的聰明,2023-05-14
- 當了媽媽后,還能有自己的疆域嗎?2023-05-14
- 國軒高科:公司是大眾SSP平臺的唯一定點供2023-05-14
- 突然宣布:停售!2023-05-14
- 【環球新要聞】手機北斗導航app下載 手機2023-05-14
- 今日熱聞!飛盧小說網官網小說 飛盧小說網官2023-05-14
- 全球信息:高質量發展調研行 | 第六屆進博2023-05-14
- 俄羅斯當局:一架俄軍直升機在俄南地區墜毀2023-05-14