亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

React?模式之純組件使用示例詳解

 更新時間:2022年08月25日 09:20:08   作者:czpcalm  
這篇文章主要為大家介紹了React?模式之純組件使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

什么是純組件

純組件(Pure Component)這概念衍生自純函數(shù)。純函數(shù)指的是返回結(jié)果只依賴于傳入的參數(shù),且對函數(shù)作用域外沒有副作用的函數(shù)。這種函數(shù)在相同參數(shù)下,返回結(jié)果是不變的。純函數(shù)的返回值能被安全地緩存起來,在下次調(diào)用時,跳過函數(shù)執(zhí)行,直接讀取緩存。因為函數(shù)沒有外部副作用,不執(zhí)行函數(shù)對整個程序沒有影響。

與純函數(shù)類似,如果一個組件在 props 和 state 相同的情況下,每次 render 的結(jié)果都是相同的,那這個組件就是純組件。也就是說,純組件的 render 結(jié)果只依賴于 props 和 state,如果兩次渲染中,props 和 state 是相同的,那它們的 render 結(jié)果也是一樣的。

純組件解決了什么問題

在理解純組件有什么用處之前,先來看一下 React 如何更新組件。

React 在更新組件時,會從觸發(fā)組件開始,遞歸地調(diào)用整顆子樹的 render 函數(shù),構(gòu)建新的虛擬樹。即使子組件的 props 和 state 沒有變化,render 函數(shù)還是會被執(zhí)行。

看這個例子:

const defaultMessage = "Hello!";
function Messager() {
  console.log("render in parent");
  const [messageInput, setMessageInput] = useState(defaultMessage);
  const [messageData, setMessageData] = useState({
    id: 0,
    message: "",
  });
  return (
    <div className="logger">
      <input
        value={messageInput}
        onChange={(e) => setMessageInput(e.target.value)}
      ></input>
      <button
        onClick={() =>
          setMessageData((preData) => ({
            id: preData.id + 1,
            message: messageInput,
          }))
        }
      >
        發(fā)送消息
      </button>
      <MessageText message={messageData.message} />
    </div>
  );
}
function MessageText(props) {
  console.log("render in child");
  return <div>最新消息:{props.message}</div>;
}

連續(xù)點擊幾次按鈕:

父組件 Messager 由于狀態(tài)更新,需要重新執(zhí)行 render 函數(shù)來更新組件,這個是符合預(yù)期的。子組件 MessageText 中,第一次更新,由于 message 屬性改變,也需要更新,這個也容易理解。

問題在后面幾次更新:

  • 子組件的 props 沒有變化,為什么執(zhí)行了 render 函數(shù)?
  • render 函數(shù)執(zhí)行了,是不是意味著 DOM 也更新了,只是我們看不出變化?
  • 組件在 props 沒有變化時,繪制的視圖都是不變的,能不能跳過 render 函數(shù)的執(zhí)行?

讓我一個一個來回答。

Q:為什么需要執(zhí)行 render 函數(shù)?

A:你的組件可能使用了任何變量,包括全局變量、環(huán)境變量等,React 沒有能力做到監(jiān)聽這些變量,這些變量的變化是 React 無法感知的。為了保證渲染的視圖與數(shù)據(jù)是一致的,React 只能犧牲性能,在每次更新的時候,都去執(zhí)行 render 函數(shù),獲取最新的 render 輸出。

Q: 執(zhí)行了 render 函數(shù)就一定會更新 DOM 嗎?

A:不一定。render 函數(shù)的輸出結(jié)果是 React 虛擬 DOM,執(zhí)行了 render 函數(shù)會更新虛擬 DOM,但 React 足夠聰明,能夠比對出瀏覽器 DOM 需要更新的地方,讓瀏覽器只進行必要的重繪。這也是 React 能夠保證性能的重要手段。

Q:能避免不必要的 render 執(zhí)行嗎?

A:可以。如果是 class 組件(CC),你可以重寫 shouldComponentUpdate() 方法或繼承 React.PureComponent。如果是函數(shù)組件(FC),你可以使用 React.memo() 。這樣能夠避免不必要的 render 執(zhí)行,在一定程度上提升頁面的性能,尤其是當 render 函數(shù)內(nèi)有復(fù)雜計算時。這也正是純組件想要解決的問題。

怎么使用純組件

CC: shouldComponentUpdate() 和 React.PureComponent

?? 這一小節(jié)的內(nèi)容基于 class 組件,F(xiàn)C 不適用。

React 組件更新前,會調(diào)用 shouldComponentUpdate(nextProps,nextState),當返回 true 時,組件就會 re-render。所以,你可以重寫這個方法,當不希望組件更新時,返回 false。

重寫上面的 MessageText 組件:

class MessageText extends React.Component {
  shouldComponentUpdate(nextProps) {
    if (nextProps.message === this.props.message) {
      return false;
    }
    return true;
  }
  render() {
    console.log("render in child with message=" + this.props.message);
    return <div>最新消息:{this.props.message}</div>;
  }
}

這樣,render 函數(shù)只會在 props.message 變化的時候才會被調(diào)用。當然,你可以自己決定哪些條件下跳過 render。

?? shouldComponentUpdate 返回 false 時并不能保證跳過 render。React 后續(xù)可能會增加自己的判斷,只把這個返回結(jié)果作為一種提示。所以這個方法應(yīng)該只能被用于性能優(yōu)化,不能作為邏輯依賴。

大部分時候,我們期望在 props 和 state 不變的時候,跳過 render,因為這經(jīng)常導(dǎo)致不必要的更新。上面的例子只有一個屬性,有點過于簡單了,組件可能會多個 props 和 state,需要在 () 中窮舉比較。

因為這種模式太過常見,React 提供了 React.PureComponent 類,你可以繼承這個類,來實現(xiàn)純組件的效果,即當 props 和 state 不變(淺比較)時,跳過 render。

class MessageText extends React.PureComponent {
  render() {
    console.log("render in child with message=" + this.props.message);
    return <div>最新消息:{this.props.message}</div>;
  }
}

FC: React.memo()

先回答一個普遍疑惑的問題。

Q:FC 是純組件嗎?或者無狀態(tài)的 FC 是純組件嗎? A:并不是。從最上面的例子就可以看出來。無狀態(tài) FC 與純組件是獨立的概念,狀態(tài)并不是影響純組件的因素,關(guān)鍵在于組件函數(shù)除了 state 和 props 有沒有外部依賴,對外部有沒有影響。

Q:既然如此,怎么把 FC 改造成純組件? A:很簡單,用 class 重寫組件并繼承 React.PureComponent 就可以了。

說笑了,這年頭,誰寫 React 還用 class 啊。

然而,很遺憾,hooks 無法覆蓋 shouldComponentUpdate() 的使用場景,F(xiàn)C 沒有等效于 React.PureComponent 的寫法。

不過,倒是可以使用 React.memo() 實現(xiàn)一個半吊子的純組件。

const memorizedFC=React.memo(FC,arePropsEqual(preProps,nextProps)=>{
    // 返回true,跳過render
    // 返回false,執(zhí)行render
})

React.memo() 把上次調(diào)用的結(jié)果保存在內(nèi)存中,下次調(diào)用時,如果 arePropsEqual() 返回 true,那就直接使用上次的結(jié)果,不需要執(zhí)行 FC。arePropsEqual 參數(shù)可選,默認使用淺比較。

利用 React.memo(), 把 MessageText 改造成純組件 PureMessageText

function MessageText(props) {
  console.log("render in child with message=" + props.message);
  return <div>最新消息:{props.message}</div>;
}
const PureMessageText = React.memo(MessageText);

注意 React.memo() 并不等效于 React.PureComponent,前者只能比較 props,對于狀態(tài)導(dǎo)致的更新,F(xiàn)C 依然會執(zhí)行。這也是為什么說是“半吊子純組件”。

如果 FC 無狀態(tài),那 React.memo() 就可以等效于 React.PureComponent 了。既然如此,對有狀態(tài) FC,可以利用狀態(tài)上移把 state 轉(zhuǎn)為 props,再應(yīng)用 React.memo(), 實現(xiàn)純組件的效果。

所以,絕大多數(shù)情況下,React.memo() 已經(jīng)足夠了。

你可能并不需要純組件

了解純組件的概念,以及它對 React 應(yīng)用性能的影響,對一個開發(fā)者有很大幫助,但這并不意味著你需要經(jīng)常使用它。

React 提供了良好的性能保證,大部分情況下,你的應(yīng)用不會有性能上的問題,使用純組件反而增加理解成本。

即使出現(xiàn)了性能問題,一些通用的性能優(yōu)化手段可能更有效果。只有當性能瓶頸出現(xiàn)在特定組件的 render,并且這個組件可以被改造成純組件時,這個措施才會有效果。

以上就是React 模式之純組件使用示例詳解的詳細內(nèi)容,更多關(guān)于React 純組件模式的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • react-router?v6新特性總結(jié)示例詳解

    react-router?v6新特性總結(jié)示例詳解

    在V6版本中,<Switch>組件被替換成<Routes>組件,同時,component屬性被element屬性替換,這篇文章主要介紹了react-router?v6新特性總結(jié),需要的朋友可以參考下
    2022-12-12
  • React Native開發(fā)封裝Toast與加載Loading組件示例

    React Native開發(fā)封裝Toast與加載Loading組件示例

    這篇文章主要介紹了React Native開發(fā)封裝Toast與加載Loading組件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • 解決React報錯Property does not exist on type 'JSX.IntrinsicElements'

    解決React報錯Property does not exist on 

    這篇文章主要為大家介紹了React報錯Property does not exist on type 'JSX.IntrinsicElements'解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • 解決React報錯Parameter 'props' implicitly has an 'any' type

    解決React報錯Parameter 'props' implicitly&nb

    這篇文章主要為大家介紹了React報錯Parameter 'props' implicitly has an 'any' type的解決處理方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • 詳解react組件通訊方式(多種)

    詳解react組件通訊方式(多種)

    這篇文章主要介紹了詳解react組件通訊方式,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • react-navigation之動態(tài)修改title的內(nèi)容

    react-navigation之動態(tài)修改title的內(nèi)容

    這篇文章主要介紹了react-navigation之動態(tài)修改title的內(nèi)容,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • React大屏可視化腳手架教程示例

    React大屏可視化腳手架教程示例

    這篇文章主要為大家介紹了React大屏可視化腳手架教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 淺談React Native 傳參的幾種方式(小結(jié))

    淺談React Native 傳參的幾種方式(小結(jié))

    這篇文章主要介紹了淺談React Native 傳參的幾種方式,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • react-router-dom v6版本跳轉(zhuǎn)路徑的實現(xiàn)方法

    react-router-dom v6版本跳轉(zhuǎn)路徑的實現(xiàn)方法

    這篇文章主要介紹了react-router-dom v6版本跳轉(zhuǎn)路徑的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 使用Jenkins部署React項目的方法步驟

    使用Jenkins部署React項目的方法步驟

    這篇文章主要介紹了使用Jenkins部署React項目的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03

最新評論