當(dāng)前快訊:React筆記-生命周期(七)
掛載階段constructor生命周期值React組件從裝載到卸載的全過程 在這個過程中React提供了多個內(nèi)置函數(shù)供開發(fā)者在不同階段執(zhí)行需要的邏輯
狀態(tài)組件由3個階段組成 掛載階段(MOUNTING) 更新階段(UPDATING) 卸載階段(UNMOUNT)
從縱向劃分為2個階段 Render階段 Commit階段
【資料圖】
Render階段 純凈且無副作用 會被React暫停 終止 重新啟動
Commit階段 可以使用DOM 有副作用
構(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被正式廢棄)
render(mounting階段)觸發(fā)時機(jī)
在構(gòu)造函數(shù)和裝載組件(將 DOM 樹渲染到瀏覽器中)之間觸發(fā)
注意
在此生命周期函數(shù)里使用 setState 同步設(shè)置組件內(nèi)部狀態(tài) state 將不會觸發(fā)重新渲染避免在該方法中引入任何的副作用(Effects)或訂閱(Subscription)。對于這些使用場景,建議提前到構(gòu)造函數(shù)中
渲染函數(shù)(這個并不是react生命周期)
componentDidMount作用: 僅用于渲染的純函數(shù) 返回值取決于state和props(并不是真實(shí)渲染 返回的是一個JSX描述文件 真實(shí)渲染取決于所有組件渲染函數(shù)后)
注意
不能在函數(shù)中任何修改 state、props、請求數(shù)據(jù)等具有副作用的操作不能讀寫 DOM 信息不能和瀏覽器進(jìn)行交互(例如 setTimeout)
觸發(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純組件componentWillUpdate這個是用于繼承 并不是生命周期(不需要開發(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)
render(updating階段)此生命周期函數(shù)將在React v17正式廢棄 使用componentWillReceiveProps代替
觸發(fā)時機(jī)
更新生命周期中重新渲染之前的最后一個方法 此時已經(jīng)擁有了更新后的屬性和狀態(tài) 并且可以在這個方法中隨意處理這些數(shù)據(jù)
注意
此函數(shù)不會在初始化渲染時候被觸發(fā)禁止在這個函數(shù)中調(diào)用setState方法 會造成死循環(huán)
getSnapshotBeforeUpdate渲染函數(shù) 與mounting階段的render一致 用于渲染被React處理過的JSX到瀏覽器
觸發(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ù)原因卸載階段componentWillUnmountcomponentWillReceiveProps | 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ā)者)
觸發(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錯誤邊界(Error Boundary)觸發(fā)時機(jī)
該生命周期函數(shù)會在子孫組件拋出錯誤時執(zhí)行
使用方式和getDerivedStateFromError一致
一般情況下 任何組件在渲染期間發(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)簽:
頭條精選
廣西壯族自治區(qū)三江侗族自治縣發(fā)布大霧黃色預(yù)警
三江縣氣象臺2023年5月15日5時44分發(fā)布大霧黃色預(yù)警信號:預(yù)計(jì)未來12小時內(nèi)我縣將出現(xiàn)能見度小于500米的大
- 當(dāng)前快訊:React筆記-生命周期(七)2023-05-15
- AI DevOps | ChatGPT 與研發(fā)效能、效率2023-05-15
- 劉強(qiáng)東很“著急”,京東變革進(jìn)行時2023-05-15
- 本周A股限售股解禁市值約366億元,環(huán)比降逾2023-05-15
- 廣西壯族自治區(qū)三江侗族自治縣發(fā)布大霧黃色2023-05-15
- 廣西壯族自治區(qū)靈川縣發(fā)布大霧黃色預(yù)警_世2023-05-15
- 恩比德:綠軍聯(lián)盟最強(qiáng) 系列賽多數(shù)時候我們2023-05-15
- 恩比德:你可以說 近兩戰(zhàn)的失利削弱了76人2023-05-15
- 交行易貸通申請條件_交行易貸通2023-05-15
- 長沙南站在哪里坐地鐵_長沙南站在哪里|天天2023-05-15
- 全球速遞!硬核科技論 | 賽車同款序列式2023-05-15
- 今日觀點(diǎn)!探野川西 新RAV4榮放長途試駕體驗(yàn)2023-05-15
- 速度與激情8演員表圖片_速度與激情8演員-當(dāng)2023-05-14
- 青島會計(jì)繼續(xù)教育考試可以考幾次_青島會計(jì)2023-05-14
- 持續(xù)降價 7.18萬就能買寶來 銷量明顯穩(wěn)了2023-05-14
- 通用汽車在美國召回99.5萬輛汽車:氣囊已致2023-05-14
- 環(huán)球今日報丨彎梁摩托車_彎梁125摩托車哪款2023-05-14
- 全球速讀:飛龍騎臉怎么輸黃旭東_飛龍騎臉2023-05-14
- 德昌縣氣象臺發(fā)布大風(fēng)藍(lán)色預(yù)警信號【IV級/2023-05-14
- 熱?熱?熱?!成都下周直沖35℃!-世界新動態(tài)2023-05-14
- 涼皮的調(diào)料汁怎么調(diào)配_好吃的陜西涼皮調(diào)料2023-05-14
- 當(dāng)前熱文:月餅怎么做的方法教程簡單_中秋2023-05-14
- 焦點(diǎn)熱門:看一個男人,是不是真正的聰明,2023-05-14
- 當(dāng)了媽媽后,還能有自己的疆域嗎?2023-05-14
- 國軒高科:公司是大眾SSP平臺的唯一定點(diǎn)供2023-05-14
- 突然宣布:停售!2023-05-14
- 【環(huán)球新要聞】手機(jī)北斗導(dǎo)航app下載 手機(jī)2023-05-14
- 今日熱聞!飛盧小說網(wǎng)官網(wǎng)小說 飛盧小說網(wǎng)官2023-05-14
- 全球信息:高質(zhì)量發(fā)展調(diào)研行 | 第六屆進(jìn)博2023-05-14
- 俄羅斯當(dāng)局:一架俄軍直升機(jī)在俄南地區(qū)墜毀2023-05-14