91aaa在线国内观看,亚洲AV午夜福利精品一区二区,久久偷拍人视频,久久播这里有免费视播

<strong id="fvuar"></strong>

  • <sub id="fvuar"><dl id="fvuar"><em id="fvuar"></em></dl></sub>

    1. 千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

      手機(jī)站
      千鋒教育

      千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

      千鋒教育

      掃一掃進(jìn)入千鋒手機(jī)站

      領(lǐng)取全套視頻
      千鋒教育

      關(guān)注千鋒學(xué)習(xí)站小程序
      隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

      當(dāng)前位置:首頁(yè)  >  技術(shù)干貨  > 為什么react選擇了函數(shù)式組件(剖析原理)

      為什么react選擇了函數(shù)式組件(剖析原理)

      來(lái)源:千鋒教育
      發(fā)布人:wjy
      時(shí)間: 2022-06-06 11:54:00 1654487640

      以下代碼,沒(méi)有使用模塊化的方式,使用的是CDN的方式。如果需要源代碼,請(qǐng)從這個(gè)地址下載:

      ```text
      鏈接:https://pan.baidu.com/s/1s57mr5AE_ecWBFZ5TJTwqw  提取碼:f7x2
      ```

      另外,這篇文章,主要是剖析**組件的初次渲染和重新渲染**。所以,其它部分不要太較勁。

      為什么react選擇了函數(shù)式組件

      ### **一、react類組件和函數(shù)式組件重新渲染時(shí)的區(qū)別**

      ### **1、看現(xiàn)象:**

      ### **1)代碼(demo01)**

      **類組件:**

      ```js
          // 1、類組件
          class ComClass extends React.Component {
              constructor(props) {
                  super();
                  this.props = props;
                  console.log("類組件的構(gòu)造函數(shù)被調(diào)用了");
              }

              render() {
                  console.log("類組件的render被調(diào)用了");
                  return (
                  <div style={{ "backgroundColor": "pink" }}>
                          <h5 >我是類組件</h5>
                          <p>{this.props.name}</p>
                      </div>
                  );
              }
          }
      ```

      **函數(shù)式組件:**

      ```js
           // 2、函數(shù)式組件
          function ComFn(props) {
              console.log("函數(shù)式組件的函數(shù)被調(diào)用了");
              return (               
                  <div style={{ "backgroundColor": "skyblue" }}>
                      <h5 >我是函數(shù)式組件</h5>
                      <p>{props.name}</p>
                  </div>
              );
          }

      ```

       

      **使用組件:**

      ```js

          let name = "張三瘋";
          function changeName() {
              name = "張四瘋"
              renderDom();
          }

          function renderDom() {
              ReactDOM.render(
                  <div>
                      <button onClick={changeName} >修改</button>
                      <ComClass name={name} /><br />
                      <ComFn name={name} />
                  </div>, document.getElementById("box"));
          }

          renderDom();

      ```

       

      ### **2)運(yùn)行:**

      2.1)初次運(yùn)行時(shí),我們發(fā)現(xiàn)在控制臺(tái)中打印的內(nèi)容為:

      ```js
      類組件的構(gòu)造函數(shù)被調(diào)用了
      類組件的render被調(diào)用了
      函數(shù)式組件的函數(shù)被調(diào)用了
      ```

       

      2.2)當(dāng)點(diǎn)擊“修改”按鈕時(shí),我們發(fā)現(xiàn)控制臺(tái)中打印的內(nèi)容為:

      ```js
      類組件的render被調(diào)用了
      函數(shù)式組件的函數(shù)被調(diào)用了
      ```

       

      ### **3)總結(jié)(敲黑板,重點(diǎn)):**

      1、類組件重新渲染時(shí),只調(diào)用了render

      2、函數(shù)式組件重新渲染時(shí),會(huì)調(diào)用函數(shù)整個(gè)本身(哈哈,不調(diào)用它也不行?。?/p>

       

      ### **2、看原理:**

      ### **1)用原生的方式剖析:**

      函數(shù)式組件的剖析:

      ```js
      標(biāo)簽的方式使用函數(shù)式組件:
      <ComFn name={name} />
      基本上等價(jià)于:
      {ComFn({name})} //組件的方式使用,就是在調(diào)用函數(shù)
      ```

      類組件的剖析:

      ```js
      標(biāo)簽的方式使用類組件:
      <ComClass name={name} /><br/>
      等價(jià)于
      {new ComClass({name}).render()}

      但是
      這樣改了后,初次渲染沒(méi)有問(wèn)題。當(dāng)點(diǎn)擊了“修改”按鈕時(shí),不一樣了。
      所以,類組件里,應(yīng)該是把new ComClass({name})實(shí)例化出來(lái)的對(duì)象,記錄起來(lái)了。所以,應(yīng)該等價(jià)于
      1、定義一個(gè)對(duì)象,保存了new ComClass({name})
         //在react里對(duì)類組件對(duì)象進(jìn)行了保存。
         let comObj = new {new ComClass({name});

      2、在渲染時(shí),只是調(diào)用了類組件的render函數(shù)。
         comObj.render();
      ```

      即:最終代碼變成了如下:

      ### **2)代碼(demo02):**

      類組件和函數(shù)式組件的代碼不用改變。

      **使用組件**

      ```js
          let name  = "張三瘋";
          //此處保存了類組件的實(shí)例化對(duì)象(這個(gè)只是模擬實(shí)現(xiàn),react內(nèi)部并不是這么簡(jiǎn)單)
          let comObj = new ComClass({name});
          function changeName(){
              name = "張四瘋";
              comObj.props = {name}
              renderDom();
          }

          function renderDom(){
              ReactDOM.render(
              <div>
                  <button onClick={changeName} >修改數(shù)據(jù)</button>
                  {/*此處用原生的方式使用組件*/}
                  {comObj.render()}
                  {ComFn({name})}
              </div>, document.getElementById("box"));
          }

          renderDom();
      ```

      ### **3)運(yùn)行:**

      3.1)、初次運(yùn)行時(shí),我們發(fā)現(xiàn)在控制臺(tái)中打印的內(nèi)容為:

      ```js
      類組件的構(gòu)造函數(shù)被調(diào)用了
      類組件的render被調(diào)用了
      函數(shù)式組件的函數(shù)被調(diào)用了
      ```

      3.2)、當(dāng)點(diǎn)擊“修改”按鈕時(shí),我們發(fā)現(xiàn)控制臺(tái)中打印的內(nèi)容為:

      ```js
      類組件的render被調(diào)用了
      函數(shù)式組件的函數(shù)被調(diào)用了
      ```

       

      > 運(yùn)行結(jié)果和組件的方式一樣。

      ### **二、看看組件里使用定時(shí)器,并且,重新渲染組件**

      ### **1、看現(xiàn)象**

      ### **1)代碼(demo03):**

      **類組件:**

      ```js
         // 1、類組件
          class ComClass extends React.Component {
              constructor(props) {
                  super();
                  this.props = props;
                  console.log("類組件的構(gòu)造函數(shù)被調(diào)用了");
              }

              showMessage = () => {
                  //在顯示props時(shí)(通過(guò)this訪問(wèn)props),props里的內(nèi)容被改變了。
                  console.log('類組件: ' + this.props.name);
              };

              handleClick = () => {
                  // 分析問(wèn)題:
                  // 1、3秒鐘后調(diào)用函數(shù)(通過(guò) this 的方式調(diào)用)
                  setTimeout(this.showMessage, 3000);
              };


              render() {
                  console.log("類組件的render被調(diào)用了");
                  return (
                      <div style={{ "backgroundColor": "pink" }}>
                          <h5 >我是類組件</h5>
                          <p>name:{this.props.name}</p>
                          <input type="button" value="調(diào)用帶著定時(shí)器的函數(shù)" onClick={this.handleClick} />
                      </div>
                  );
              }
          }   
      ```

      **函數(shù)式組件:**

      ```js
      // 2、函數(shù)式組件
          function ComFn(props) {
              console.log("函數(shù)式組件的函數(shù)被調(diào)用了");

              //這個(gè)是閉包:
              // 每調(diào)用一次父函數(shù)(ComFn),都會(huì)重新定義一個(gè)新的子函數(shù)。新的函數(shù)中保存著父函數(shù)新的形參
              const showMessage = () => {
                  console.log('函數(shù)式組件: ' + props.name);
              };

              //這個(gè)是閉包:
              //每調(diào)用一次父函數(shù)(ComFn),都會(huì)重新定義一個(gè)新的子函數(shù)。新的函數(shù)中保存著父函數(shù)新的形參
              const handleClick = () => {
                  setTimeout(showMessage, 3000);
              };
             
              return (
                  <div style={{ "backgroundColor": "skyblue" }}>
                      <h5 >我是函數(shù)式組件</h5>
                      <p>name:{props.name}</p>
                      {/*先點(diǎn)擊這個(gè)按鈕,調(diào)用,第一次定義的 showMessage和handleClick*/}
                      <input type="button" value="調(diào)用帶著定時(shí)器的函數(shù)" onClick={handleClick} />
                  </div>
              );
          }
      ```

      **使用組件:**

      ```js
        let name = "張三瘋";
          function changeName() {
              name = "張四瘋"
              renderDom();
          }

          function renderDom() {
              ReactDOM.render(
                  <div>
                      <button onClick={changeName} >修改</button>
                      <ComClass name={name} /><br />
                      <ComFn name={name} />
                  </div>, document.getElementById("box"));
          }

          renderDom();
      ```

      為什么react選擇了函數(shù)式組件1

      ### **2)、運(yùn)行:**

      **2.1)類組件:**

      點(diǎn)擊類組件的“調(diào)用帶著定時(shí)器的函數(shù)” 按鈕后,再點(diǎn)擊”修改“按鈕(**注意先后順序**)。我們發(fā)現(xiàn)了:界面上打印的和控制臺(tái)打印的是**一樣的**。這是**不對(duì)的**:因?yàn)?,我點(diǎn)擊“調(diào)用帶著定時(shí)器的函數(shù)” 按鈕時(shí),name的值是”張三瘋“,應(yīng)該打印”張三瘋“

      為什么react選擇了函數(shù)式組件2

      **2.2)函數(shù)式組件:**

      點(diǎn)擊類組件的“調(diào)用帶著定時(shí)器的函數(shù)” 按鈕后,再點(diǎn)擊”修改“按鈕(**注意先后順序**)。我們發(fā)現(xiàn)了:界面上打印的和控制臺(tái)里打印的**不一樣**,這是**對(duì)的**:因?yàn)?,我點(diǎn)擊“調(diào)用帶著定時(shí)器的函數(shù)” 按鈕時(shí),name的值是”張三瘋“,應(yīng)該打印”張三瘋“

      為什么react選擇了函數(shù)式組件3

      ### **3)總結(jié)**

      原因何在?以下文字要細(xì)細(xì)的品,如果品不出來(lái),就結(jié)合上面的代碼,再看看。

      類組件:

      當(dāng)**類組件重新渲染**時(shí),**只調(diào)用了render函數(shù)**。組件的this不變。等定時(shí)器到了時(shí),讀取屬性的的值時(shí),先通過(guò)this找到props。再通過(guò)props找到name。而此時(shí),name的值,已經(jīng)發(fā)生了變化。所以,自然讀到的是新值“張四瘋” ,這個(gè)應(yīng)該好理解。

      函數(shù)式組件:

      (你必須對(duì)閉包是清楚的),當(dāng)**函數(shù)式組件重新渲染**時(shí),**調(diào)用了函數(shù)**(組件),那么在函數(shù)式組件里的 函數(shù)(showMessage,handleClick)就會(huì)被重新定義,新定義的函數(shù)保存著父函數(shù)(組件)的新的形參和局部變量。而我們點(diǎn)擊“調(diào)用帶著定時(shí)器的函數(shù)”時(shí),調(diào)用的是 第一次定義的showMessage,handleClick(這兩個(gè)函數(shù)里保存了父函數(shù)(組件)第一次傳入的形參和局部變量)。

      其實(shí),上面的代碼中,已經(jīng)做了注釋。我再次解釋后,如果不明白的話,看看下面的剖析原理的代碼。

       

      ### **2、看原理:**

      ### **1)用原生的方式剖析**

      與第一大點(diǎn)的第二小點(diǎn)的“剖析原理”一樣:

      函數(shù)式組件的剖析:

      ```js
      標(biāo)簽的方式使用函數(shù)式組件:
      <ComFn name={name} />
      基本上等價(jià)于:
      {ComFn({name})} //組件的方式使用,就是在調(diào)用函數(shù)
      ```

      類組件的剖析:

      ```js
      把new ComClass({name})實(shí)例化出來(lái)的對(duì)象,記錄起來(lái)了。

      1、定義一個(gè)對(duì)象,保存了new ComClass({name})
         //在react里對(duì)類組件對(duì)象進(jìn)行了保存。
         let comObj = new {new ComClass({name});

      2、在渲染時(shí),只是調(diào)用了類組件的render函數(shù)。
         comObj.render();
      ```

      ### **2)代碼(demo04):**

      類組件和函數(shù)式組件的代碼不用變(同第二大點(diǎn)的第一小點(diǎn):組件里使用定時(shí)器,并重新渲染組件)。

      **使用組件:**

      這個(gè)代碼等同于第一大點(diǎn)的第二小點(diǎn)。

      ```js
       let name = "張三瘋";
          let comObj = new ComClass({ name });
          function changeName() {
              name = "張四瘋";
              comObj.props = { name }
              renderDom();
          }

          function renderDom() {       
              ReactDOM.render(
                  <div>
                      <button onClick={changeName} >修改</button>
                      {comObj.render()}
                      {ComFn({name})}
                  </div>, document.getElementById("box"));
          }

          renderDom();

      ```

       

      ### **三、為什么react現(xiàn)在更推薦函數(shù)式組件**

      為什么react選擇了函數(shù)式組件4

      React的核心理念之一就是,**界面應(yīng)當(dāng)是數(shù)據(jù)的不同形式的簡(jiǎn)單投影**。**相同的輸入應(yīng)該產(chǎn)生相同的輸出**。而函數(shù)式組件的寫(xiě)法,使用閉包的特性,顯然符合這一理念:每個(gè)閉包里保存在父函數(shù)的當(dāng)前形參(props)和局部變量。而類組件里,由于,每次讀取數(shù)據(jù),要根據(jù)this指針去讀取,那必然不會(huì)讀取到屬于自己當(dāng)前狀態(tài)的值。而是更新后的最新的值。

       

      ### **四、補(bǔ)充:類組件如何解決以上問(wèn)題呢:**

      其實(shí)還是利用了閉包。

      ### **看類組件的代碼修改(demo05):**

       

      ```js
      //修改類組件里的showMessage 和 handleClick 函數(shù)。

      showMessage = (name) => {
          console.log('類組件: ' + name);
      };

      handleClick = () => {
          let name = this.props.name;
          //此處:
          //1 、()=>this.showMessage(name)是閉包。父函數(shù)是handleClick,
          //2、閉包會(huì)把當(dāng)前的局部變量name持有,然后,調(diào)用 showMessage(name)時(shí),把name的值傳入showMessge里
          setTimeout(()=>this.showMessage(name), 3000);
      };

      ```

       

      ### **五、類組件和函數(shù)式組件區(qū)別:**

      在react的模式和開(kāi)發(fā)思維上,函數(shù)組件和類組件還是有區(qū)別的。

      1、各自的特點(diǎn):

      1)類的組件主要是面向?qū)ο缶幊?,是建立在繼承之上,它的生命周期等核心概念的特點(diǎn)  2)函數(shù)組件主要是函數(shù)式編程,無(wú)副作用,并且在引用的時(shí)候透明的特點(diǎn)

      2、使用場(chǎng)景:

      因?yàn)閮烧咧鞔虻奶攸c(diǎn)不一樣,所以在使用場(chǎng)景上自然就存在一些差異了: 如果組件依賴生命周期,并且它的設(shè)計(jì)上需要繼承的特性,我們?cè)谶x擇上更傾向類組件會(huì)更合適一點(diǎn)

      由于HOOK的推出,逐漸降低了生命周期的概念,那么函數(shù)組件可以更好的取代類組件的開(kāi)發(fā),而且官方也推崇“組合優(yōu)于繼承”的思想,所以類組件的優(yōu)勢(shì)也在慢慢的淡出。更多關(guān)于web培訓(xùn)的問(wèn)題,歡迎咨詢千鋒教育在線名師。千鋒教育擁有多年IT培訓(xùn)服務(wù)經(jīng)驗(yàn),采用全程面授高品質(zhì)、高體驗(yàn)培養(yǎng)模式,擁有國(guó)內(nèi)一體化教學(xué)管理及學(xué)員服務(wù),助力更多學(xué)員實(shí)現(xiàn)高薪夢(mèng)想。

      tags:
      聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
      10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
      請(qǐng)您保持通訊暢通,專屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
      免費(fèi)領(lǐng)取
      今日已有369人領(lǐng)取成功
      劉同學(xué) 138****2860 剛剛成功領(lǐng)取
      王同學(xué) 131****2015 剛剛成功領(lǐng)取
      張同學(xué) 133****4652 剛剛成功領(lǐng)取
      李同學(xué) 135****8607 剛剛成功領(lǐng)取
      楊同學(xué) 132****5667 剛剛成功領(lǐng)取
      岳同學(xué) 134****6652 剛剛成功領(lǐng)取
      梁同學(xué) 157****2950 剛剛成功領(lǐng)取
      劉同學(xué) 189****1015 剛剛成功領(lǐng)取
      張同學(xué) 155****4678 剛剛成功領(lǐng)取
      鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
      董同學(xué) 138****2867 剛剛成功領(lǐng)取
      周同學(xué) 136****3602 剛剛成功領(lǐng)取
      相關(guān)推薦HOT
      抖音小店照片要求尺寸多大

      在抖音平臺(tái)開(kāi)設(shè)小店已經(jīng)成為了越來(lái)越多人的選擇,相信大家已經(jīng)在各大社交平臺(tái)上看到有不少小店的推廣。在抖音上,照片是展示產(chǎn)品的重要手段,因...詳情>>

      2023-10-08 16:14:25
      抖音招商團(tuán)長(zhǎng)托管服務(wù)費(fèi)怎么退回來(lái)

      抖音招商團(tuán)長(zhǎng)托管服務(wù)是抖音為有意愿創(chuàng)作內(nèi)容并帶動(dòng)其他創(chuàng)作者成為團(tuán)隊(duì)成員的用戶提供的一種服務(wù)。通過(guò)該服務(wù),招商團(tuán)長(zhǎng)可以自主組建團(tuán)隊(duì)并得到...詳情>>

      2023-10-08 16:08:53
      抖音小店怎么做代銷

      抖音已經(jīng)成為了一個(gè)非常受歡迎的短視頻應(yīng)用程序,在其中許多用戶都精心打造了自己的小店,用于銷售各種各樣的商品,獲取額外的收入。然而,要想...詳情>>

      2023-10-08 15:28:41
      怎樣開(kāi)抖音小店帶貨賺錢

      隨著直播帶貨的火熱,越來(lái)越多的人開(kāi)始嘗試通過(guò)抖音小店來(lái)開(kāi)展帶貨業(yè)務(wù)。抖音小店是抖音直播帶貨的配套,可以讓用戶在購(gòu)買直播中產(chǎn)品時(shí)就實(shí)現(xiàn)購(gòu)...詳情>>

      2023-10-08 15:06:36
      能不能幫我打開(kāi)抖音小店店鋪呢怎么弄

      抖音小店是近年來(lái)非?;鸨囊粋€(gè)網(wǎng)絡(luò)業(yè)務(wù),也是提供了很多商業(yè)機(jī)會(huì)的平臺(tái)。對(duì)于一個(gè)創(chuàng)業(yè)者而言,開(kāi)設(shè)抖音小店是一個(gè)不錯(cuò)的選擇。但是,許多小店...詳情>>

      2023-10-08 15:01:21
      快速通道