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

React.memo 實(shí)現(xiàn)原理解析

 更新時間:2025年09月09日 11:10:45   作者:維維醬  
React.memo通過props淺比較或自定義函數(shù),結(jié)合Fiber優(yōu)化機(jī)制,跳過組件渲染及副作用,下面就來詳細(xì)的介紹一下,感興趣的可以了解一下

核心實(shí)現(xiàn)概念

React.memo 的本質(zhì)是一個高階組件(HOC),它通過比較前后 props 來決定是否跳過組件的重新渲染。

1. 基本結(jié)構(gòu)

在 React 源碼中,React.memo 的實(shí)現(xiàn)大致如下:

function memo(type, compare) {
  // 創(chuàng)建一個特殊的元素類型
  const elementType = {
    $$typeof: REACT_MEMO_TYPE, // 特殊標(biāo)識符,表示這是一個 memo 組件
    type, // 被包裹的原始組件
    compare: compare === undefined ? null : compare, // 自定義比較函數(shù)
  };
  
  return elementType;
}

2. 在協(xié)調(diào)(Reconciliation)過程中的處理

當(dāng) React 遇到 REACT_MEMO_TYPE 類型的元素時,會執(zhí)行特殊處理:

// 簡化版的協(xié)調(diào)邏輯
function updateMemoComponent(
  currentFiber, // 當(dāng)前 Fiber 節(jié)點(diǎn)
  workInProgressFiber, // 工作中的 Fiber 節(jié)點(diǎn)
  Component, // 被 memo 包裹的組件
  nextProps, // 新的 props
  renderLanes // 渲染優(yōu)先級
) {
  // 獲取之前的 props
  const current = currentFiber.memoizedProps;
  
  // 決定使用哪種比較函數(shù)
  let compare = Component.compare;
  if (compare === null) {
    // 默認(rèn)使用淺比較
    compare = shallowCompare;
  }
  
  // 檢查 props 是否相等
  if (compare(current, nextProps)) {
    // Props 沒有變化,完全跳過渲染
    // 復(fù)用之前的子節(jié)點(diǎn)
    return bailoutOnAlreadyFinishedWork(
      currentFiber,
      workInProgressFiber,
      renderLanes
    );
  }
  
  // Props 發(fā)生了變化,繼續(xù)正常渲染流程
  return updateFunctionComponent(
    currentFiber,
    workInProgressFiber,
    Component,
    nextProps,
    renderLanes
  );
}

深入實(shí)現(xiàn)細(xì)節(jié)

1. 淺比較 (shallowCompare) 的實(shí)現(xiàn)

React 使用的默認(rèn)淺比較函數(shù)類似于:

function shallowCompare(prevProps, nextProps) {
  // 如果 props 對象引用相同,直接返回 true
  if (prevProps === nextProps) {
    return true;
  }
  
  // 檢查 props 鍵的數(shù)量
  const prevKeys = Object.keys(prevProps);
  const nextKeys = Object.keys(nextProps);
  
  if (prevKeys.length !== nextKeys.length) {
    return false;
  }
  
  // 逐個比較每個屬性值
  for (let i = 0; i < prevKeys.length; i++) {
    const key = prevKeys[i];
    
    // 使用 Object.is 進(jìn)行嚴(yán)格比較(類似于 ===,但處理了 NaN 和 +0/-0 的情況)
    if (!Object.is(prevProps[key], nextProps[key])) {
      return false;
    }
  }
  
  return true;
}

2. Fiber 架構(gòu)中的優(yōu)化機(jī)制

在 React 的 Fiber 架構(gòu)中,React.memo 的優(yōu)化是通過以下機(jī)制實(shí)現(xiàn)的:

  • 提前中止渲染:在 beginWork 階段,如果檢測到是 memo 組件且 props 未變化,React 會立即中止當(dāng)前組件的渲染工作。
  • 子樹復(fù)用:通過 bailoutOnAlreadyFinishedWork 函數(shù),React 會標(biāo)記整個子樹為"無需更新",直接復(fù)用之前的渲染結(jié)果。
  • 跳過副作用:由于組件沒有重新渲染,相關(guān)的副作用(如 useEffect)也不會被觸發(fā)。

3. 與 React 渲染流程的整合

// 簡化的渲染流程
function beginWork(currentFiber, workInProgressFiber, renderLanes) {
  // 檢查是否是 memo 組件
  if (workInProgressFiber.type && workInProgressFiber.type.$$typeof === REACT_MEMO_TYPE) {
    return updateMemoComponent(
      currentFiber,
      workInProgressFiber,
      workInProgressFiber.type.type, // 提取原始組件
      workInProgressFiber.pendingProps,
      renderLanes
    );
  }
  
  // 處理其他類型的組件...
}

性能考慮與實(shí)現(xiàn)優(yōu)化

1. 記憶化策略

React.memo 的實(shí)現(xiàn)采用了記憶化(Memoization)策略:

  • 存儲之前的結(jié)果:React 會存儲組件上一次的渲染結(jié)果(在 Fiber 節(jié)點(diǎn)的 memoizedStatememoizedProps 中)
  • 比較成本與渲染成本的權(quán)衡:淺比較的計(jì)算成本遠(yuǎn)低于組件的渲染成本(包括虛擬 DOM 創(chuàng)建和差異比較)

2. 選擇性優(yōu)化

React 不會對所有組件都應(yīng)用 memo 優(yōu)化,因?yàn)椋?/p>

  • 比較本身有成本
  • 對于頻繁更新或 props 經(jīng)常變化的組件,memo 可能帶來負(fù)收益

3. 與其他優(yōu)化機(jī)制的協(xié)同

React.memo 與 React 的其他優(yōu)化機(jī)制協(xié)同工作:

  • Context 優(yōu)化:即使使用 React.memo,如果組件消費(fèi)的 Context 值發(fā)生變化,組件仍會重新渲染
  • 狀態(tài)更新優(yōu)化:組件內(nèi)部的狀態(tài)更新不受 React.memo 影響

實(shí)際應(yīng)用中的實(shí)現(xiàn)考慮

1. 自定義比較函數(shù)的高級用法

// 深度比較實(shí)現(xiàn)(不推薦在生產(chǎn)環(huán)境使用,僅作示例)
function deepCompare(prevProps, nextProps) {
  return JSON.stringify(prevProps) === JSON.stringify(nextProps);
}

// 選擇性比較
function selectiveCompare(prevProps, nextProps) {
  // 只比較我們關(guān)心的屬性
  return prevProps.importantValue === nextProps.importantValue;
}

const ExpensiveComponent = React.memo(
  function ExpensiveComponent(props) {
    // 組件實(shí)現(xiàn)
  },
  selectiveCompare // 使用自定義比較函數(shù)
);

2. 與 Hooks 的交互

React.memo 的實(shí)現(xiàn)需要考慮與 Hooks 的交互:

function MyComponent(props) {
  // 即使使用 React.memo,內(nèi)部狀態(tài)變化仍會導(dǎo)致重新渲染
  const [state, setState] = useState(0);
  
  // 使用 useMemo 和 useCallback 可以進(jìn)一步優(yōu)化
  const computedValue = useMemo(() => {
    return expensiveCalculation(props.someValue);
  }, [props.someValue]);
  
  const handleClick = useCallback(() => {
    // 處理點(diǎn)擊
  }, []);
  
  return <div>{/* ... */}</div>;
}

export default React.memo(MyComponent);

總結(jié)

React.memo 的實(shí)現(xiàn)原理可以概括為:

  1. 高階組件包裝:通過創(chuàng)建特殊類型的 React 元素標(biāo)記 memo 組件
  2. 協(xié)調(diào)階段攔截:在協(xié)調(diào)過程中識別 memo 組件并執(zhí)行特殊處理
  3. Props 比較:使用淺比較或自定義比較函數(shù)判斷 props 是否變化
  4. 渲染優(yōu)化:如果 props 未變化,跳過組件的渲染和子樹的協(xié)調(diào)過程
  5. 結(jié)果復(fù)用:直接復(fù)用之前的渲染結(jié)果,避免不必要的計(jì)算和 DOM 操作

這種實(shí)現(xiàn)方式體現(xiàn)了 React 性能優(yōu)化的核心思想:用較小的比較成本換取可能很大的渲染成本節(jié)約。

到此這篇關(guān)于React.memo 實(shí)現(xiàn)原理解析的文章就介紹到這了,更多相關(guān)React.memo實(shí)現(xiàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React事件處理的機(jī)制及原理

    React事件處理的機(jī)制及原理

    這篇文章主要介紹了React事件處理的機(jī)制及原理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • React精髓!一篇全概括小結(jié)(急速)

    React精髓!一篇全概括小結(jié)(急速)

    這篇文章主要介紹了React精髓!一篇全概括小結(jié)(急速),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • React項(xiàng)目打包發(fā)布到Tomcat頁面空白問題及解決

    React項(xiàng)目打包發(fā)布到Tomcat頁面空白問題及解決

    這篇文章主要介紹了React項(xiàng)目打包發(fā)布到Tomcat頁面空白問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • ReactHook使用useState更新變量后,如何拿到變量更新后的值

    ReactHook使用useState更新變量后,如何拿到變量更新后的值

    這篇文章主要介紹了ReactHook使用useState更新變量后,如何拿到變量更新后的值問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • React 的虛擬 DOM 機(jī)制及原理解析

    React 的虛擬 DOM 機(jī)制及原理解析

    React的虛擬DOM機(jī)制通過在內(nèi)存中生成和比較虛擬DOM樹,實(shí)現(xiàn)了高效的渲染和性能優(yōu)化,是React框架的核心特點(diǎn),本文給大家介紹React的虛擬DOM機(jī)制及原理解析,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • 教你快速搭建 React Native 開發(fā)環(huán)境

    教你快速搭建 React Native 開發(fā)環(huán)境

    這篇文章主要介紹了搭建 React Native 開發(fā)環(huán)境的詳細(xì)過程,本文通過圖文指令給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • react-router JS 控制路由跳轉(zhuǎn)實(shí)例

    react-router JS 控制路由跳轉(zhuǎn)實(shí)例

    這篇文章主要介紹了react-router JS 控制路由跳轉(zhuǎn)實(shí)例,react實(shí)現(xiàn)路由可以直接使用react-router。有興趣的可以了解一下
    2017-06-06
  • 詳解React Native與IOS端之間的交互

    詳解React Native與IOS端之間的交互

    React Native (簡稱RN)是Facebook于2015年4月開源的跨平臺移動應(yīng)用開發(fā)框架,是Facebook早先開源的JS框架 React 在原生移動應(yīng)用平臺的衍生產(chǎn)物,支持iOS和安卓兩大平臺。本文將介紹React Native與IOS端之間的交互。
    2021-06-06
  • 使用useEffect模擬組件生命周期

    使用useEffect模擬組件生命周期

    這篇文章主要介紹了使用useEffect模擬組件生命周期,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 使用 React 和 Threejs 創(chuàng)建一個VR全景項(xiàng)目的過程詳解

    使用 React 和 Threejs 創(chuàng)建一個VR全景項(xiàng)目的過程詳解

    這篇文章主要介紹了使用 React 和 Threejs 創(chuàng)建一個VR全景項(xiàng)目的過程詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04

最新評論

黔西县| 淅川县| 五大连池市| 克东县| 土默特左旗| 松潘县| 商都县| 河南省| 常德市| 鄂托克旗| 滨海县| 山西省| 子洲县| 阳东县| 车致| 稻城县| 明水县| 岳普湖县| 左云县| 千阳县| 崇州市| 津南区| 水城县| 庐江县| 贵港市| 奉节县| 报价| 凤城市| 德江县| 灵石县| 中牟县| 荔波县| 宕昌县| 亳州市| 中阳县| 郁南县| 新巴尔虎左旗| 荃湾区| 兰西县| 怀宁县| 临颍县|