最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React類組件更新的底層邏輯案例詳解

 更新時間:2025年01月21日 16:30:25   作者:不叫貓先生  
這篇文章主要介紹了React類組件的更新過程,包括組件初始化、更新和卸載的生命周期方法,以及如何使用setState和forceUpdate來控制視圖的更新,感興趣的朋友一起看看吧

創(chuàng)建一個構(gòu)造函數(shù)(類)

  • 類組件必須繼承自 React.ComponentReact.PureComponent。
  • 在類組件中,需要定義 render 方法來返回需要渲染的視圖。
  • 通常使用ES6中的class創(chuàng)建類。
class MyComponent extends React.Component {
  constructor(props) {
    super(props); // 調(diào)用父類構(gòu)造函數(shù)
    console.log(this.props); // 獲取傳遞的屬性
    this.state = { count: 0 }; // 初始化狀態(tài)
  }
  //返回渲染的視圖
  render() {
    return <div>{this.state.count}</div>;
  }
}

類組件初始化

1. 初始化屬性 && 規(guī)則校驗

首先會進行規(guī)則校驗,校驗完畢后,再處理屬性的其他操作。處理傳進來的屬性有兩種處理方式:

方案一:

  constructor(props) {
        super(props); //會把傳遞進來的屬性掛載到this實例上
        console.log(this.props); //獲取到傳遞的屬性
  }

方案二:

不在constructor中處理「或者constructor都沒寫」,在constructor處理完畢后,React內(nèi)部也會把傳遞的props掛載到實例上。所以在其他的函數(shù)中,只要保證this是實例,就可以基于this.props獲取傳遞的屬性。同樣this.props獲取的屬性對象也是被凍結(jié)的{只讀的} Object.isFrozen(this.props)->true

2. 初始化狀態(tài)

狀態(tài):后期修改狀態(tài),可以觸發(fā)視圖的更新。需要手動初始化,如果我們沒有去做相關(guān)的處理,則默認會往實例上掛載一個state,初始值是null => this.state=null, 手動處理則需要寫個state對象:

state = {
    ...
  };

如何修改狀態(tài),控制視圖更新

  this.state.xxx=xxx

上面的操作僅僅是修改了狀態(tài)值,但是無法讓視圖更新,想讓視圖更新,我們需要基于React.Component.prototype提供的方法操作:

this.setState(partialState) 既可以修改狀態(tài),也可以讓視圖更新 「推薦」 ,其中partialState部分狀態(tài)

 this.setState({
       xxx:xxx
  });

this.forceUpdate() 強制更新

3、觸發(fā) componentWillMount

componentWillMount:組件第一次渲染之前觸發(fā)。

鉤子函數(shù):在程序運行到某個階段,我們可以基于提供一個處理函數(shù),讓開發(fā)者在這個階段做一些自定義的事情

??注意:此周期函數(shù),目前是不安全的「雖然可以用,但是未來可能要被移除了,所以不建議使用」,控制會拋出黃色警告「為了不拋出警告,我們可以暫時用 UNSAFE_componentWillMount

??注意:如果開啟了React.StrictMode「React的嚴格模式」,則我們使用 UNSAFE_componentWillMount 這樣的周期函數(shù),控制臺會直接拋出紅色警告錯誤?。?/p>

React.StrictMode VS “use strict”

  • “use strict”:JS的嚴格模式
  • React.StrictMode:React的嚴格模式,它會去檢查React中一些不規(guī)范的語法、或者是一些不建議使用的API等??!

4、觸發(fā) render 進行渲染

5、觸發(fā) componentDidMount

componentDidMount:第一次渲染完畢,此時已經(jīng)把virtualDOM變?yōu)檎鎸岲OM了,可以獲取真實DOM

組件更新的邏輯

第一種:組件內(nèi)部的狀態(tài)被修改,組件會更新

1、觸發(fā) shouldComponentUpdate

shouldComponentUpdate:是否允許更新,返回值決定視圖是否需要更新

   shouldComponentUpdate(nextProps, nextState) {
     // nextState:存儲要修改的最新狀態(tài)
     // this.state:存儲的還是修改前的狀態(tài)「此時狀態(tài)還沒有改變」
     console.log(this.state, nextState);
     // 此周期函數(shù)需要返回true/false
     //   返回true:允許更新,會繼續(xù)執(zhí)行下一個操作
     //   返回false:不允許更新,接下來啥都不處理
     return true;
   }

2、觸發(fā) componentWillUpdate

componentWillUpdate:更新之前,此周期函數(shù)也是不安全的, 在這個階段,狀態(tài)/屬性還沒有被修改。

3、修改狀態(tài)值/屬性值

this.state.xxx改為最新的值

4、觸發(fā) render

進行組件渲染,處于經(jīng)歷下面過程:

  • 按照最新的狀態(tài)/屬性,把返回的JSX編譯為virtualDOM
  • 和上一次渲染出來的virtualDOM進行對比「DOM-DIFF
  • 把差異的部分進行渲染「渲染為真實的DOM」

5、 觸發(fā) componentDidUpdate

componentDidUpdate:組件更新完畢。

??注意:如果我們是基于 this.forceUpdate() 強制更新視圖,會跳過 shouldComponentUpdate 周期函數(shù)的校驗,直接從 componentWillUpdate 開始進行更新,也就是視圖一定會觸發(fā)更新。

第二種:父組件更新,觸發(fā)的子組件更新

1、觸發(fā) componentWillReceiveProps

componentWillReceiveProps:接收最新屬性之前,該周期函數(shù)是不安全的。

  UNSAFE_componentWillReceiveProps(nextProps) {
      // this.props:存儲之前的屬性
      // nextProps:傳遞進來的最新屬性值
      console.log('componentWillReceiveProps:', this.props, nextProps);
  }

2、觸發(fā) shouldComponentUpdate 周期函數(shù)

接下來的邏輯跟第一種一樣

組件卸載的邏輯

觸發(fā) componentWillUnmount

componentWillUnmount:組件銷毀之前

銷毀

擴展:父子組件嵌套更新邏輯

父子組件嵌套,處理機制上遵循深度優(yōu)先原則:父組件在操作中,遇到子組件,一定是把子組件處理完,父組件才能繼續(xù)處理

父組件第一次渲染

父 willMount -> 父 render「子 willMount -> 子 render -> 子didMount」 -> 父didMount

父組件更新

父 shouldUpdate -> 父willUpdate -> 父 render 「子willReceiveProps -> 子 shouldUpdate -> 子willUpdate -> 子 render -> 子 didUpdate」-> 父 didUpdate

父組件銷毀

父 willUnmount -> 處理中「子willUnmount -> 子銷毀」-> 父銷毀

源碼

import React from "react";
import PropTypes from 'prop-types';
class Vote extends React.Component {
  /* 屬性規(guī)則校驗 */
  static defaultProps = {
    num: 0
  };
  static propTypes = {
    title: PropTypes.string.isRequired,
    num: PropTypes.number
  };
  /* 初始化狀態(tài) */
  state = {
    supNum: 20,
    oppNum: 10
  };
  render() {
    console.log('render:渲染');
    let { title } = this.props,
      { supNum, oppNum } = this.state;
    return <div className="vote-box">
      <div className="header">
        <h2 className="title">{title}</h2>
        <span>{supNum + oppNum}人</span>
      </div>
      <div className="main">
        <p>支持人數(shù):{supNum}人</p>
        <p>反對人數(shù):{oppNum}人</p>
      </div>
      <div className="footer">
        <button onClick={() => {
          this.setState({
            supNum: supNum + 1
          });
        }}>支持</button>
        <button onClick={() => {
          this.state.oppNum++;
          this.forceUpdate();
        }}>反對</button>
      </div>
    </div>;
  }
  UNSAFE_componentWillMount() {
    console.log('componentWillMount:第一次渲染之前');
  }
  componentDidMount() {
    console.log('componentDidMount:第一次渲染完畢');
  }
  shouldComponentUpdate(nextProps, nextState) {
    console.log('shouldComponentUpdate:', this.state, nextState);
    return true;
  }
  UNSAFE_componentWillUpdate(nextProps, nextState) {
    console.log('componentWillUpdate:', this.state, nextState);
  }
  componentDidUpdate() {
    console.log('componentDidUpdate:組件更新完畢');
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    console.log('componentWillReceiveProps:', this.props, nextProps);
  }
  componentWillUnmount() {
    console.log('componentWillUnmount:組件銷毀之前');
  }
}
export default Vote;

初始渲染:

點擊支持:更新渲染:

點擊反對,更新渲染,因為使用了forceUpdate(),所以直接跳過了shouldComponentUpdate周期:

父組件更新,觸發(fā)的子組件更新,這次回觸發(fā)componentWillReceiveProps

組件更新渲染邏輯如下圖所示

簡單總結(jié)一下:

組件初始化階段

  • constructor(props):用于初始化組件的屬性和狀態(tài)。
  • UNSAFE_componentWillMount():在組件渲染前調(diào)用,但不推薦使用,可能在未來版本中被移除。
  • render():渲染組件,返回 JSX 元素。
  • componentDidMount():在組件渲染完成后調(diào)用,可以在此進行異步操作或 DOM 操作。

組件更新階段

  • shouldComponentUpdate(nextProps, nextState):用于決定組件是否需要更新,返回 true 或 false。
  • UNSAFE_componentWillUpdate(nextProps, nextState):在組件更新前調(diào)用,但不推薦使用,未來可能移除。
  • `render():再次渲染組件。
  • componentDidUpdate(prevProps, prevState):組件更新后調(diào)用,可以在此進行后續(xù)操作。

組件卸載階段

  • componentWillUnmount():在組件銷毀之前調(diào)用,可以在此進行清理操作,如取消訂閱、清除定時器等。

到此這篇關(guān)于React類組件更新的底層邏輯的文章就介紹到這了,更多相關(guān)React類組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • react?表單數(shù)據(jù)形式配置化設(shè)計

    react?表單數(shù)據(jù)形式配置化設(shè)計

    這篇文章主要介紹了react表單數(shù)據(jù)形式配置化設(shè)計,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-07-07
  • react中fetch之cors跨域請求的實現(xiàn)方法

    react中fetch之cors跨域請求的實現(xiàn)方法

    本篇文章主要介紹了react中fetch之cors跨域請求的實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • React useEffect使用教程

    React useEffect使用教程

    useEffect是react v16.8新引入的特性。我們可以把useEffect hook看作是componentDidMount、componentDidUpdate、componentWillUnmounrt三個函數(shù)的組合
    2022-10-10
  • 瀏覽器中視頻播放器實現(xiàn)的基本思路與代碼

    瀏覽器中視頻播放器實現(xiàn)的基本思路與代碼

    這篇文章主要給大家介紹了關(guān)于瀏覽器中視頻播放器實現(xiàn)的基本思路與代碼,并且詳細總結(jié)了瀏覽器中的音視頻知識,對大家的理解和學(xué)習(xí)非常有幫助,需要的朋友可以參考下
    2021-08-08
  • 從零搭建Webpack5-react腳手架的實現(xiàn)步驟(附源碼)

    從零搭建Webpack5-react腳手架的實現(xiàn)步驟(附源碼)

    本文主要介紹了從零搭建Webpack5-react腳手架的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • hooks中useEffect()使用案例詳解

    hooks中useEffect()使用案例詳解

    這篇文章主要介紹了hooks中useEffect()使用總結(jié),本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • React使用公共文件夾public問題

    React使用公共文件夾public問題

    這篇文章主要介紹了React使用公共文件夾public問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • React+hook實現(xiàn)聯(lián)動模糊搜索

    React+hook實現(xiàn)聯(lián)動模糊搜索

    這篇文章主要為大家詳細介紹了如何利用React+hook+antd實現(xiàn)聯(lián)動模糊搜索功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • react源碼合成事件深入解析

    react源碼合成事件深入解析

    這篇文章主要為大家介紹了react源碼合成事件深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • 快速創(chuàng)建React項目并配置webpack

    快速創(chuàng)建React項目并配置webpack

    這篇文章主要介紹了創(chuàng)建React項目并配置webpack,在這里需要注意,Create?React?App?requires?Node?14?or?higher.需要安裝高版本的node,本文給大家介紹的非常詳細,需要的朋友參考下吧
    2022-01-01

最新評論

荣昌县| 嘉义县| 萍乡市| 东乡族自治县| 朝阳市| 济源市| 昌宁县| 庆阳市| 奉化市| 建宁县| 大同县| 新巴尔虎左旗| 金华市| 乌兰察布市| 怀宁县| 巴中市| 隆安县| 太和县| 正镶白旗| 沛县| 乌审旗| 聂拉木县| 灌阳县| 连云港市| 昌都县| 长岛县| 元阳县| 渑池县| 高尔夫| 贵德县| 延边| 六盘水市| 怀集县| 通道| 淮滨县| 黎城县| 文登市| 保德县| 萍乡市| 宜良县| 昌吉市|