9. React組件生命周期

2. React組件生命周期

  • 2.1. 認識生命周期
    • 2.1.1. 很多事物都有從創建到銷毀的整個過程,這個過程稱之為生命周期;
    • 2.1.2. React組件也有自己的生命周期,了解生命周期可以讓我們在最合適的地方完成想要的功能
    • 2.1.3. 生命周期和生命周期函數的關系:
      • 2.1.3.1. 生命周期是一個抽象的概念,在生命周期的整個過程,分成了很多個階段;
        • 比如掛載階段(Mount), 組件第一次在DOM樹中被渲染的過程;
        • 比如更新階段(Update), 組件狀態發生變化時,重新更新渲染的過程;
        • 比如卸載階段(Unmount), 組件從DOM樹中移除的過程;
      • 2.1.3.2. React內部為了告訴我們當前處于那些階段,會對組件內部實現的某些函數進行回調,這些函數就是生命周期函數
        • 比如實現componentDidMount函數組件已經掛載到DOM上時,就會回調;
        • 比如實現componentDidUpdate函數組件已經更新時,就會回調;
        • 比如實現componentWillUnmount函數組件即將被移除時,就會回調;
        • 可以在這些回調函數中編寫自己的邏輯代碼,來完成自己的需求功能;
    • 2.1.4. React生命周期時,主要指的是類的生命周期,因為函數式組件是沒有生命周期函數的(后面可以通過hooks來模擬一些生命周期的回調,寫到hooks會在進行記錄)
  • 2.2. 生命周期解析
    • 2.2.1. 先來了解下最基礎、最常用的生命周期函數:compentDidMountcomponentDidUpdatecomponentWillUnmount函數

    • 2.2.2. 生命周期函數如圖:官網圖譜地址
      在這里插入圖片描述
      在這里插入圖片描述

    • 2.2.3. 掛載階段:componentDidMount

        1. 在掛載時,首先會創建一個組件實例,在創建實例的過程中,就會執行類中constructor函數(每次引入使用組件時,創建的是ReactElement, 每次調用就創建一個組件實例, 每次創建實例時,就會先執行constructor函數)
        -> 類實例class Person {} ->const p1 = new Person() -> 類實例
        
        1. 緊接著調用類中的render方法
        1. 掛載完成后會調用的componentDidMount函數
        1. 如下圖:
          在這里插入圖片描述
        1. 示例代碼如下:
        • HelloWorld.jsx
          //import React from 'react';class HelloWorld extends React.Component {// 1.構造方法:constructorconstructor () {console.log('HelloWorld constructor')super();this.state = {message: 'Hello World'}}// 2.執行render方法render () {console.log('HelloWorld render')return (<div><h2>Hello World</h2><p>Hello World是程序員的第一個代碼</p></div>)}// 3.組件被渲染到DOM:被掛載到DOM上componentDidMount () {console.log('HelloWorld componentDidMount')}}export default HelloWorld;
        
        • App.jsx
          import React from "react";import HelloWorld from "./HelloWorld";class App extends React.Component {render () {return (<div>哈哈哈哈{/* 組件每引用一次,就創建一個實例,每創建一次組件實例,就會先執行constructor函數 */}<HelloWorld /><HelloWorld />{/* <HelloWorld /><HelloWorld /> */}</div>)}}export default App;
        
    • 2.2.4. 更新階段:componentDidUpdate

        1. 當數據發生更新時,執行setState方法
        1. 執行setState方法后,重新渲染頁面, 重新執行render方法,它會根據最新修改之后的message,重新生成一個新的樹,然后在進行diff算法,然后決定要更新那部分
        1. react會更新dom和refs,并調用componentDidUpdate方法
        1. 如下圖:
          在這里插入圖片描述
        • 關鍵代碼如下;
             // 4.組件的DOM被更新完成:DOM發生更新componentDidUpdate () {/***    * - 1. 當數據發生更新時,執行setState方法* - 2. 執行setState方法后,重新渲染頁面, 重新執行render方法,它會根據最新修改之后的message,重新生成一個新的樹,然后在進行diff算法,然后決定要更新那部分* - 3. react會更新dom和refs,并調用componentDidUpdate方法* * * */console.log('HelloWorld componentDidUpdate')}
          
        • 詳細代碼如下:
            import React from 'react';class HelloWorld extends React.Component {// 1.構造方法:constructorconstructor () {console.log('HelloWorld constructor')super();this.state = {message: 'Hello World'}}changeText () {this.setState({ message: '你好啊 李銀河' })}// 2.執行render方法render () {const { message } = this.stateconsole.log('HelloWorld render')return (<div><h2>{message}</h2><button onClick={e => this.changeText()}>修改文本</button><p>{message}是程序員的第一個代碼</p></div>)}// 3.組件被渲染到DOM:被掛載到DOM上componentDidMount () {/***    * - 1. 在掛載時,首先會創建一個組件實例,在創建實例的過程中,就會執行類中`constructor函數`(每次引入使用組件時,創建的是ReactElement, 每次調用就創建一個組件實例, 每次創建實例時,就會先執行constructor函數)* - 2. 緊接著調用類中的`render方法`* - 3. 掛載完成后會調用的`componentDidMount函數`* * * */ console.log('HelloWorld componentDidMount')}// 4.組件的DOM被更新完成:DOM發生更新componentDidUpdate () {/***    * - 1. 當數據發生更新時,執行setState方法* - 2. 執行setState方法后,重新渲染頁面, 重新執行render方法,它會根據最新修改之后的message,重新生成一個新的樹,然后在進行diff算法,然后決定要更新那部分* - 3. react會更新dom和refs,并調用componentDidUpdate方法* * * */console.log('HelloWorld componentDidUpdate')}}export default HelloWorld;
          
    • 2.2.5. 卸載階段:componentWillUnmount

        1. 當組件從 DOM 中移除時,會調用 componentWillUnmount() 方法。
        1. 如下圖:
          在這里插入圖片描述
        1. 示例代碼:
        • 關鍵代碼:
          // 5.組件從DOM中卸載掉:從DOM移除掉componentWillUnmount () {console.log('HelloWorld componentWillUnmount')}
        
        1. 完整代碼:
        • HelloWorld.jsx
          import React from 'react';class HelloWorld extends React.Component {// 1.構造方法:constructorconstructor () {console.log('HelloWorld constructor')super();this.state = {message: 'Hello World'}}changeText () {this.setState({ message: '你好啊 李銀河' })}// 2.執行render方法render () {const { message } = this.stateconsole.log('HelloWorld render')return (<div><h2>{message}</h2><p>{message}是程序員的第一個代碼</p><button onClick={e => this.changeText()}>修改文本</button></div>)}// 3.組件被渲染到DOM:被掛載到DOM上componentDidMount () {/***    * - 1. 在掛載時,首先會創建一個組件實例,在創建實例的過程中,就會執行類中`constructor函數`(每次引入使用組件時,創建的是ReactElement, 每次調用就創建一個組件實例, 每次創建實例時,就會先執行constructor函數)* - 2. 緊接著調用類中的`render方法`* - 3. 掛載完成后會調用的`componentDidMount函數`* * * */ console.log('HelloWorld componentDidMount')}// 4.組件的DOM被更新完成:DOM發生更新componentDidUpdate () {/***    * - 1. 當數據發生更新時,執行setState方法* - 2. 執行setState方法后,重新渲染頁面, 重新執行render方法,它會根據最新修改之后的message,重新生成一個新的樹,然后在進行diff算法,然后決定要更新那部分* - 3. react會更新dom和refs,并調用componentDidUpdate方法* * * */console.log('HelloWorld componentDidUpdate')}// 5.組件從DOM中卸載掉:從DOM移除掉componentWillUnmount () {console.log('HelloWorld componentWillUnmount')}}export default HelloWorld;
        
        • App.jsx
        import React from "react";
        import HelloWorld from "./HelloWorld";class App extends React.Component {constructor () {super();this.state = {isSHowHw: true}}switchShowHw () {this.setState ({ isSHowHw: !this.state.isSHowHw })}render () {const { isSHowHw } = this.state;return (<div>哈哈哈哈{/* 組件每引用一次,就創建一個實例,每創建一次組件實例,就會先執行constructor函數 */}<button onClick={ e => this.switchShowHw() }>切換</button>{ isSHowHw && <HelloWorld />}</div>) }
        }export default App;
        
    • 2.2.6. 開發中常用的是:constructor()、render()、componentDidMount()、componentWillUnmount()

  • 2.3. 生命周期函數
    • 2.3.1. constructor
        1. 如果不初始化state或不進行方法綁定,則不需要為React組件實現構造函數。
        1. constructor中通常只做兩件事:
        • 通過給this.state賦值對戲那個初始化內部的state;
        • 為事件綁定實例(this);
    • 2.3.2 componentDidMount
        1. componentDidMount()會在組件掛載之后(插入DOM樹中)立即調用
        1. componentDidMount中通過進行那些操作?
        • 2.1. 依賴于DOM的操作可以在這里進行;
        • 2.2. 再次是發送網絡請求最好的地方(官方建議)
        • 2.3. 可以在此處添加一些訂閱(在componentWillUnmount中取消訂閱,不然會內存泄漏)
    • 2.3.3 componentDidUpdate
        1. componentDidUpdate()會在組件更新之后立即調用, 首次渲染不會執行此方法;
        • 當組件更新后,可以在此處對DOM進行操作;
        • 如果對更新前后的props進行了比較,也可以選擇在此處進行網絡請求(例如:當props未發生變化時,則不會執行網絡請求)
    • 2.3.4 componentWillUnmount
        1. componentWillUnmount()會在組件卸載以及銷毀之前直接調用。
        • 在此方法中執行必要的清理操作;
        • 例如:清楚timer, 取消網絡請求或清除在componentDidMount中創建的訂閱等;
  • 2.4. 不常用的生命周期函數
    • 2.4.1. 不常用的生命周期如下圖:
      在這里插入圖片描述

    在這里插入圖片描述

    • 2.4.2. 不常用生命周期多出來這些方法:getDerivedStateFromProps()、shouldComponentUpdate()、getSnapshotBeforeUpdate()

    • 2.4.3. getDerivedStateFromProps()

        1. getDerivedStateFromProps():在更新或者第一次掛載時,如果state里面的數據需要依賴Props, 可以在這個回調函數里完成,這個函數用的非常少
        1. getDerivedStateFromProps(): state的值在任何使用時候依賴于props時候用,該方法返回一個對象來更新state
    • 2.4.4. shouldComponentUpdate ()

        1. shouldComponentUpdate(): 該生命周期函數很常用,等記錄到性能優化時再詳細記錄;
        1. 組件是否需要更新(shouldComponentUpdate翻譯:組件要不要更新),返回true或者false,默認是true。
        1. 當通過setState去更新數據的時候,render函數一般會直接執行,重新渲染,如果在shouldComponentUpdate生命周期里面返回false,render()不會執行,組件不會重新渲染。
        1. 某些情況下返回false,可以提高性能
    • 2.4.5. getSnapshotBeforeUpdate()

        1. getSnapshotBeforeUpdate():React更新DOM之前回調的一個函數,可以獲取DOM更新前的一些信息(例如:滾動位置)
        1. (Snapshot:快照)在組件更新之前,獲取快照,保存一些數據,返回值會作為參數傳遞給componentDidUpdate()方法。
      • 在這里插入圖片描述
    • 2.4.6. 更詳細的生命周期相關的內容,可以參考官網:官網

    • 2.4.7. 不常用生命周期函數代碼示例如下:

      • 關鍵代碼:
        // 6.不常用的生命周期補充shouldComponentUpdate () {// 是否需要重新更新,默認為true,重新更新render函數,重新渲染return true}getSnapshotBeforeUpdate () {console.log('getSnapshotBeforeUpdate')return {scrollPosition: 1000}}
      
      • 完整代碼:
        import React from 'react';class HelloWorld extends React.Component {// 1.構造方法:constructorconstructor () {console.log('HelloWorld constructor')super();this.state = {message: 'Hello World'}}changeText () {this.setState({ message: '你好啊 李銀河' })}// 2.執行render方法render () {const { message } = this.stateconsole.log('HelloWorld render')return (<div><h2>{message}</h2><p>{message}是程序員的第一個代碼</p><button onClick={e => this.changeText()}>修改文本</button></div>)}// 3.組件被渲染到DOM:被掛載到DOM上componentDidMount () {/***    * - 1. 在掛載時,首先會創建一個組件實例,在創建實例的過程中,就會執行類中`constructor函數`(每次引入使用組件時,創建的是ReactElement, 每次調用就創建一個組件實例, 每次創建實例時,就會先執行constructor函數)* - 2. 緊接著調用類中的`render方法`* - 3. 掛載完成后會調用的`componentDidMount函數`* * * */ console.log('HelloWorld componentDidMount')}// 4.組件的DOM被更新完成:DOM發生更新componentDidUpdate (prevProps, prevState, snapshot) {/***    * - 1. 當數據發生更新時,執行setState方法* - 2. 執行setState方法后,重新渲染頁面, 重新執行render方法,它會根據最新修改之后的message,重新生成一個新的樹,然后在進行diff算法,然后決定要更新那部分* - 3. react會更新dom和refs,并調用componentDidUpdate方法* * * */    console.log('HelloWorld componentDidUpdate: ', prevProps, prevState, snapshot)}// 5.組件從DOM中卸載掉:從DOM移除掉componentWillUnmount () {console.log('HelloWorld componentWillUnmount')}// 6.不常用的生命周期補充shouldComponentUpdate () {// 是否需要重新更新,默認為true,重新更新render函數,重新渲染, 返回false, 不執行render,不重新渲染界面return true}getSnapshotBeforeUpdate () {console.log('getSnapshotBeforeUpdate')return {scrollPosition: 1000}}}export default HelloWorld;
      

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/93182.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/93182.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/93182.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【單板硬件開發】關于復位電路的理解

閱讀紫光同創供應商提供的FPGA單板硬件開發手冊&#xff0c;發現復位電路他們家解釋的很通俗易懂&#xff0c;所以分享一下。如下圖&#xff0c;RST_N 是低有效的異步全芯片復位信號&#xff0c;一般外部連接電路有 3 種形式如圖 3–2&#xff0c;可根據實際需要選擇合適的電路…

《Unity Shader入門精要》學習筆記一

1、本書的源代碼 https://github.com/candycat1992/Unity_Shaders_Book 2、第1章 Shader是面向GPU的工作方式 3、第2章 渲染流水線 Shader&#xff1a;著色器 渲染流水線&#xff1a;目標是渲染一張二維紋理&#xff0c;輸入是一個虛擬攝像機、一些光源、一些Shader以及紋…

從零到一:TCP 回聲服務器與客戶端的完整實現與原理詳解

目錄 一、TCP 通信的核心邏輯 二、TCP 服務器編程步驟 步驟 1&#xff1a;創建監聽 Socket 步驟 2&#xff1a;綁定地址與端口&#xff08;bind&#xff09; 步驟 3&#xff1a;設置監聽狀態&#xff08;listen&#xff09; 步驟 4&#xff1a;接收客戶端連接&#xff08…

MyBatis-Plus核心內容

MyBatis-Plus MyBatis-Plus 是一個基于 MyBatis的增強工具&#xff0c;旨在簡化開發過程&#xff0c;減少重復代碼。它在MyBatis的基礎上增加了CRUD操作封裝&#xff0c;條件構造器、代碼生成器等功能。 一、核心特性與優勢 1. 核心特性 無侵入&#xff1a;只做增強不做改變&am…

計算機網絡摘星題庫800題筆記 第4章 網絡層

第4章 網絡層4.1 網絡層概述題組闖關1.在 Windows 的網絡配置中&#xff0c;“默認網關” 一般被設置為 ( ) 的地址。 A. DNS 服務器 B. Web 服務器 C. 路由器 D. 交換機1.【參考答案】C 【解析】只有在計算機上正確安裝網卡驅動程序和網絡協議&#xff0c;并正確設置 IP 地址信…

非root用戶在linux中配置zsh(已解決ncurses-devel報錯)

Zsh&#xff08;Z Shell&#xff09;是一款功能強大的交互式 Unix shell&#xff0c;以其高度可定制性和豐富的功能著稱&#xff0c;被視為 Bash 的增強替代品。它支持智能補全、主題美化、插件擴展&#xff08;如 Oh My Zsh 框架&#xff09;、自動糾錯、全局別名等特性&#…

《Foundations and Recent Trends in Multimodal Mobile Agents: A Survey》論文精讀筆記

論文鏈接&#xff1a;https://arxiv.org/pdf/2411.02006 摘要 文章首先介紹了核心組件&#xff0c;并探討了移動基準和交互環境中的關鍵代表性作品&#xff0c;旨在全面理解研究重點及其局限性。 接著&#xff0c;將這些進展分為兩種主要方法&#xff1a; 基于提示的方法&a…

npm安裝時一直卡住的解決方法

npm install 卡住通常是由于網絡問題或緩存問題導致的。以下是幾種解決方法&#xff1a; 方法1&#xff1a;清理npm緩存 npm cache clean --force npm install方法2&#xff1a;刪除node_modules和package-lock.json重新安裝 rm -rf node_modules package-lock.json npm instal…

[密碼學實戰]使用Java生成國密SM2加密證書等(四十三)

[密碼學實戰]使用Java生成國密SM2加密證書等(四十三) 本文將詳細介紹如何通過Java代碼生成符合國密標準的SM2加密證書,包括密鑰對生成、證書擴展屬性配置、PEM格式保存等關鍵步驟。 一. 運行結果示例 二. 國密算法與加密證書 國密算法(SM系列)是中國自主研發的密碼算法體…

從零開始之stm32之CAN通信

從小白的視角了解并實現簡單的STM32F103的CAN通信&#xff0c;直接上手。一、CAN協議簡介CAN總線上傳輸的信息稱為報文&#xff0c;當總線空閑時任何連接的單元都可以開始發送新的報文&#xff0c;有5種類型的幀&#xff1a;數據幀、遙控幀、錯誤幀、過載幀、幀間隔。數據幀有兩…

Java 課程,每天解讀一個簡單Java之利用條件運算符的嵌套來完成此題:學習成績>=90分的同學用A表示,60-89分之間的用B表示, * 60分以下

package ytr250812;/*題目&#xff1a;利用條件運算符的嵌套來完成此題&#xff1a;學習成績>90分的同學用A表示&#xff0c;60-89分之間的用B表示&#xff0c;* 60分以下*/import java.util.Scanner;public class GradeEvaluator {public static void main(String[] args) …

Word XML 批注范圍克隆處理器

該類用于處理 Word 文檔&#xff08;XML 結構&#xff09;中被批注標記的文本范圍&#xff0c; 實現指定內容的深度克隆&#xff0c;并將其插入到目標節點之后。 適用于在生成或修改 .docx 文件時復制批注內容塊。/*** Word XML 批注范圍克隆處理器* * 該類用于處理 Word 文檔&…

MQTT:Java集成MQTT

目錄Git項目路徑一、原生java架構1.1 導入POM文件1.2 編寫測試用例二、SpringBoot集成MQTT2.1 導入POM文件2.2 在YML文件中增加配置2.3 新建Properties配置文件映射配置2.4 創建連接工廠2.5 增加入站規則配置2.6 增加出站規則配置2.7 創建消息發送網關2.8 測試消息發送2.9 項目…

day 16 stm32 IIC

1.IIC概述1基于對話的形式完成&#xff0c;不需要同時進行發送和接收所以刪掉了一根數據線&#xff0c;變成半雙工2為了安全起見添加了應答機制3可以接多個模塊&#xff0c;且互不干擾4異步時序&#xff0c;要求嚴格&#xff0c;發送過程中不能暫停&#xff0c;所以需要同步時序…

AMD KFD的BO設計分析系列 0:開篇

開啟我始終不敢碰的GPU存儲系列&#xff0c;先上個圖把核心關系表達下&#xff0c;以此紀念。注&#xff1a;圖中kfdm_mm誤寫&#xff0c;應該為kfd_mm&#xff0c;不修改了&#xff0c;請大家不要介意。

EUDR的核心內容,EUDR認證的好處,EUDR意義

近年來&#xff0c;全球森林退化問題日益嚴峻&#xff0c;毀林行為不僅加劇氣候變化&#xff0c;還威脅生物多樣性和原住民權益。為應對這一挑戰&#xff0c;歐盟于2023年6月正式實施《歐盟零毀林法案》&#xff08;EU Deforestation-free Regulation, EUDR&#xff09;&#x…

數據分析專欄記錄之 -基礎數學與統計知識

數據分析專欄記錄之 -基礎數學與統計知識&#xff1a; 1、描述性統計 均值 data_set [10, 20, 30, 40, 50] mean sum(data_set)/len(data_set)np 里面的函數&#xff0c;對二維進行操作時&#xff0c; 默認每一列 mean1 np.mean(data_set) print(mean, mean1)s 0 for i…

《星辰建造師:C++多重繼承的奇幻史詩》

&#x1f30c;&#x1f525; 《星辰建造師&#xff1a;多重繼承與this指針的終極史詩》 &#x1f525;&#x1f30c;—— 一場融合魔法、科技與哲學的C奇幻冒險&#x1f320;&#x1f30c; 序章&#xff1a;代碼宇宙的誕生 &#x1f30c;&#x1f320;在無盡的代碼維度中&#…

云計算-OpenStack 運維開發實戰:從 Restful API 到 Python SDK 全場景實現鏡像上傳、用戶創建、云主機部署全流程

一、python-Restful Api 簡介 Restful API 是一種軟件架構風格,基于 HTTP 協議設計,通過統一的接口(如 URL 路徑)和標準的 HTTP 方法(GET/POST/PUT/DELETE 等)實現資源(如數據、文件等)的操作,具有無狀態、可緩存、客戶端 - 服務器分離等特點。方法如下 用 GET 請求獲…

RxJava 在 Android 中的深入解析:使用、原理與最佳實踐

前言RxJava 是一個基于觀察者模式的響應式編程庫&#xff0c;它通過可觀察序列和函數式操作符的組合&#xff0c;簡化了異步和事件驅動程序的開發。在 Android 開發中&#xff0c;RxJava 因其強大的異步處理能力和簡潔的代碼風格而廣受歡迎。本文將深入探討 RxJava 的使用、核心…