React.memo、useMemo 和 React.PureComponent的區別

useMemo 和 React.memo 都是 React 提供的性能優化工具,但它們的作用和使用場景有顯著不同。以下是兩者的全面對比:

一、核心區別總結

特性useMemoReact.memo
類型React Hook高階組件(HOC)
作用對象緩存計算結果緩存組件渲染結果
優化目標避免重復計算避免不必要的子組件重新渲染
觸發條件依賴項變化時重新計算props變化時重新渲染
使用位置組件內部組件定義外層
返回值記憶化的值記憶化的組件

二、useMemo 深度解析

1、基本用法

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

2、主要特點

  • 緩存計算值:只有當依賴項變化時才重新計算
  • 組件內部使用:只能在函數組件或自定義Hook中使用
  • 不阻止渲染:只是優化計算過程,不影響組件是否渲染

3、典型場景

function Component({ items }) {// 只有items變化時才重新計算排序結果const sortedItems = useMemo(() => {return items.sort((a, b) => a.value - b.value);}, [items]);return <List items={sortedItems} />;
}

三、React.memo 深度解析

1、基本用法

const MemoizedComponent = React.memo(Component, arePropsEqual?);

注意:這里傳遞了第二個參數,它是一個自定義比較函數,用于決定是否跳過重新渲染 比如下面案例中 當判斷條件為true時候 跳過渲染

2、主要特點

  • 組件記憶化:對組件進行淺比較,props不變時跳過渲染
  • 類似PureComponent:用于函數組件的shouldComponentUpdate
  • 可自定義比較:通過第二個參數控制比較邏輯

3、典型場景

const Child = React.memo(function Child({ data }) {return <div>{data.value}</div>;
});function Parent() {const [count, setCount] = useState(0);return (<><button onClick={() => setCount(c => c + 1)}>Re-render Parent</button><Child data={{ value: "Static" }} /> {/* 不會隨Parent重渲染 */}</>);
}

四、關鍵區別

1、作用層次不同

  • useMemo:優化組件內部的計算過程
  • React.memo:優化整個組件的渲染行為

2、依賴檢測方式

// useMemo 顯式聲明依賴
const value = useMemo(() => a + b, [a, b]);// React.memo 自動淺比較props
const MemoComp = React.memo(Comp);
// 或自定義比較
const MemoComp = React.memo(Comp, (prev, next) => prev.id === next.id); // 當上一次值和這次值的id 不一樣的時候  就會觸發渲染

3、性能影響對比

操作useMemo影響React.memo影響
組件重新渲染仍會執行,但可能跳過計算可能完全跳過子組件渲染
內存占用緩存計算結果緩存組件實例
適用粒度細粒度(單個值)粗粒度(整個組件)

五、聯合使用示例

// 優化計算 + 優化渲染的完美組合
const ExpensiveComponent = React.memo(function({ items }) {const processedItems = useMemo(() => {return items.map(item => ({...item,fullName: `${item.firstName} ${item.lastName}`}));}, [items]);return (<ul>{processedItems.map(item => (<li key={item.id}>{item.fullName}</li>))}</ul>);
});function Parent() {const [count, setCount] = useState(0);const [items] = useState([...]);return (<><button onClick={() => setCount(c => c + 1)}>Render {count}</button><ExpensiveComponent items={items} /> {/* 父組件重渲染時,子組件不會重新渲染 */}</>);
}

六、使用建議

  • 優先考慮 React.memo:當需要防止不必要的子組件重渲染時
  • 合理使用 useMemo:對于計算量大的派生數據
  • 不要過度優化:簡單的組件和計算不需要使用
  • 注意引用類型:兩者都依賴淺比較,注意對象/數組的引用穩定性

七、常見誤區

1、錯誤期待

// 以為能阻止子組件渲染(實際無效)
const Child = () => {const data = useMemo(() => ({ value: 1 }), []);return <div>{data.value}</div>;
}
// 正確做法是用React.memo包裹組件

2、錯誤依賴

// 依賴項不全可能導致過時閉包
const value = useMemo(() => a + b + c, [a, b]); // 缺少c

3、錯誤嵌套

// 不需要用useMemo緩存React.memo組件
const MemoComp = useMemo(() => React.memo(Comp), []); // 多余

八、React.memo和React.PureComponent區別

1、PureComponent 的核心作用

  • 自動實現 shouldComponentUpdate()普通 React.Component 在父組件更新或自身狀態變化時總會重新渲染,而 PureComponent 會先淺比較 props 和 state,只有數據真正變化時才會觸發渲染
  • 避免不必要的渲染,適用于數據變化不頻繁或props/state 是簡單類型(非深層嵌套對象) 的場景。

2、與 React.Component 的區別

特性React.ComponentReact.PureComponent
是否自動比較 props/state? 每次父組件更新或自身狀態變化都會重新渲染? 僅當 props/state 淺比較不同時才重新渲染
適用場景需要手動優化或復雜數據變化時數據簡單、變化不頻繁時
性能優化需要手動實現shouldComponentUpdate()自動優化,減少不必要的渲染

3、適用場景

? 推薦使用 PureComponent 的情況:

  • props/state 是基本類型(string, number, boolean 等)
  • props/state 是簡單對象(沒有深層嵌套)
  • 組件渲染成本高(如長列表、復雜計算)

? 不推薦使用 PureComponent 的情況:

  • props/state 包含深層嵌套對象(淺比較無法檢測內部變化)
  • 使用了可變數據(如直接修改數組或對象)
  • 需要自定義 shouldComponentUpdate 邏輯

4、代碼示例

import React from 'react';// 使用 PureComponent 替代 Component
class MyComponent extends React.PureComponent {render() {console.log("只有 props/state 變化時才會重新渲染!");return <div>{this.props.value}</div>;}
}

5、注意事項

1、 淺比較(shallow compare)的局限性:PureComponent 只對比 props/state 的第一層,如果數據是深層嵌套的(如 { user: { name: ‘Alice’ } }),修改 user.name 不會觸發重新渲染(因為 user 對象的引用沒變
2、避免直接修改 state(應使用不可變數據)

// ? 錯誤:直接修改數組,PureComponent 無法檢測變化
this.state.items.push(newItem);
this.setState({ items: this.state.items }); // 不會觸發重新渲染// ? 正確:返回新數組
this.setState({ items: [...this.state.items, newItem] }); // 會觸發重新渲染

九、PureComponent 和 React.memo 的區別

1、適用組件類型不同

卻別PureComponentReact.memo
適用組件Class 組件函數組件
替代方案繼承 React.PureComponent用 React.memo() 包裹函數組件
示例class MyComp extends React.PureComponentconst MyComp = React.memo(() => {…})

2、比較方式

兩者都默認使用 淺比較(shallow compare),但 React.memo 更靈活:

  • PureComponent:自動比較 props 和 state,只要其中任何一個變化就重新渲染
  • React.memo:默認只比較 props(函數組件沒有 state),但可以自定義比較邏輯

3、對 state 的處理

PureComponentReact.memo
是否比較 state? 比較 props 和 state? 只比較 props(函數組件依賴 useState/useReducer 管理狀態
狀態變化是否觸發渲染? state 變化會觸發重新渲染? state 變化不影響 memo(由 React Hooks 內部處理)

4、使用場景

? PureComponent 適用場景:

  • Class 組件,且 props/state 是簡單數據類型或淺層對象
  • 不需要自定義 shouldComponentUpdate 邏輯

? React.memo 適用場景:

  • 函數組件,且 props 是簡單數據類型或淺層對象
  • 需要自定義比較邏輯(如深層比較某些 props)

5、代碼對比

(1)PureComponent(Class 組件)

import React from 'react';class MyComponent extends React.PureComponent {render() {return <div>{this.props.value}</div>;}
}

(2)React.memo(函數組件)

import React from 'react';const MyComponent = React.memo(function MyComponent(props) {return <div>{props.value}</div>;
});

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

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

相關文章

Lumerical INTERCONNECT ------ CW Laser 和 OPWM 組成的系統

Lumerical INTERCONNECT ------ CW Laser 和 OPWM 組成的系統 引言 正文 引言 這里我們來簡單介紹一下 CW Laser 與 OSA 組成的簡單系統結構的仿真。 正文 我們構建一個如下圖所示的仿真結構。 我們將 CWL 中的 power 設置為 1 W。 然后直接運行仿真查看結果如下: 雖然 …

想漲薪30%?別只盯著大廠了!轉型AI產品經理的3個通用方法,人人都能學!

在AI產品經理剛成為互聯網公司香餑餑的時候&#xff0c;剛做產品1年的月月就規劃了自己的轉型計劃&#xff0c;然后用3個月時間成功更換賽道&#xff0c;轉戰AI產品經理&#xff0c;漲薪30%。 問及她有什么上岸秘訣&#xff1f;她也復盤總結了3個踩坑經驗和正確路徑&#xff0c…

基于Hadoop的全國農產品批發價格數據分析與可視化與價格預測研究

文章目錄有需要本項目的代碼或文檔以及全部資源&#xff0c;或者部署調試可以私信博主項目介紹每文一語有需要本項目的代碼或文檔以及全部資源&#xff0c;或者部署調試可以私信博主 項目介紹 隨著我國農業數字化進程的加快&#xff0c;農產品批發市場每天都會產生海量的價格…

STM32在使用DMA發送和接收時的模式區別

在STM32的DMA傳輸中&#xff0c;發送使用DMA_Mode_Normal而接收使用DMA_Mode_Circular的設計基于以下關鍵差異&#xff1a;1. ?觸發機制的本質區別??發送方向&#xff08;TX&#xff09;?&#xff1a;由USART的?TXE標志&#xff08;發送寄存器空&#xff09;觸發?&#x…

【秋招筆試】2025.08.15餓了么秋招機考-第三題

?? 點擊直達筆試專欄 ??《大廠筆試突圍》 ?? 春秋招筆試突圍在線OJ ?? 筆試突圍在線刷題 bishipass.com 03. A先生的商貿網絡投資 問題描述 A先生是一位精明的商人,他計劃在 n n n 個城市之間建立商貿網絡。目前有 m m

Socket 套接字的學習--UDP

上次我們大概介紹了一些關于網絡的基礎知識&#xff0c;這次我們利用編程來深入學習一下一&#xff1a;套接字Socket1.1什么是Socketsocket API 是一層抽象的網絡編程接口,適用于各種底層網絡協議,如 IPv4、IPv6,. 然而, 各種網絡協議的地址格式并不相同。1.2套接字的分類套接字…

AI - MCP 協議(一)

AI應用開發的高級特性——MCP模型上下文協議&#xff0c;打通AI與外部服務的邊界。 ************************************************************************************************************** 一、需求分析 當你的AI具備了RAG的能力&#xff0c;具備了調用工具的…

在es中安裝kibana

一 安裝 1.1 驗證訪問https的連通性 # 測試 80 端口&#xff08;HTTP&#xff09; curl -I -m 5 http://目標IP:端口號 說明&#xff1a; -I&#xff1a;僅獲取 HTTP 頭部&#xff08;Head 請求&#xff09;&#xff0c;不下載正文&#xff0c;減少數據傳輸。 -m 5&#x…

嵌入式開發學習———Linux環境下網絡編程學習(二)

UDP服務器客戶端搭建UDP服務器代碼#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h>#define PORT 8080 #define BUFFER_SIZE 1024int main() {int sockfd;char buffer[BUFFER_SIZE…

UVa1465/LA4841 Searchlights

UVa12345 UVa1465/LA4841 Searchlights題目鏈接題意輸入格式輸出格式分析AC 代碼題目鏈接 本題是2010年icpc亞洲區域賽杭州賽區的I題 題意 在一個 n 行 m 列&#xff08;n≤100&#xff0c;m≤10 000&#xff09;的網格中有一些探照燈&#xff0c;每個探照燈有一個最大亮度 k&…

詳解區塊鏈技術及主流區塊鏈框架對比

文章目錄一、區塊鏈技術棧詳解二、主流區塊鏈框架對比1. 公有鏈&#xff08;Public Blockchain&#xff09;2. 聯盟鏈&#xff08;Consortium Blockchain&#xff09;3. 私有鏈&#xff08;Private Blockchain&#xff09;三、技術選型建議1. 按需求選擇框架2. 開發工具與生態四…

大模型 + 垂直場景:搜索 / 推薦 / 營銷 / 客服領域開發有哪些新玩法?

技術文章大綱&#xff1a;大模型 垂直場景的新玩法大模型與搜索領域的結合大模型在搜索領域的應用可以顯著提升搜索結果的準確性和用戶體驗。利用大模型進行語義理解和上下文關聯&#xff0c;能夠實現更精準的意圖識別。結合知識圖譜和動態索引優化&#xff0c;可以增強長尾查…

p5.js 3D盒子的基礎用法

點贊 關注 收藏 學會了 如果你剛接觸 p5.js&#xff0c;想嘗試 3D 繪圖&#xff0c;那么box()函數絕對是你的入門首選。它能快速繪制出 3D 長方體&#xff08;或正方體&#xff09;&#xff0c;配合簡單的交互就能做出酷炫的 3D 效果。本文會從基礎到進階&#xff0c;帶你吃…

【動態規劃 完全背包 卡常】P9743 「KDOI-06-J」旅行|普及+

本文涉及知識點 C動態規劃 完全背包 C記憶化搜索 「KDOI-06-J」旅行 題目描述 小 C 在 C 國旅行。 C 國有 nmn\times mnm 個城市&#xff0c;可以看做 nmn\times mnm 的網格。定義 (i,j)(i,j)(i,j) 表示在網格中第 iii 行第 jjj 列的城市。 該國有 222 種交通系統&#x…

pytest框架-詳解

目錄 一、前言 二、pytest安裝 2.1、安裝 2.2、驗證安裝 2.3、pytest文檔 三、pytest框架的約束 3.1、 python的命名規則 3.2、 pytest的命名規則 四、pytest的運行方式 4.1、主函數運行 4.2、命令行運行 五、pytest配置文件pytest.ini文件 六、前置和后置 七、as…

【遞歸、搜索與回溯算法】DFS解決FloodFill算法

FloodFill算法簡介一、[圖像渲染](https://leetcode.cn/problems/flood-fill/description/)二、[島嶼數量](https://leetcode.cn/problems/number-of-islands/description/)三、[島嶼的最大面積](https://leetcode.cn/problems/max-area-of-island/description/)四、[被圍繞的區…

解決網絡傳輸中可能出現的“粘包”

先理解核心問題&#xff1a;什么是“TCP粘包”&#xff1f; TCP 就像一條水管&#xff0c;數據通過水管從一端傳到另一端。但它有個特點&#xff1a;不會按“發送時的小包”來劃分&#xff0c;而是把數據當成連續的字節流。 比如&#xff1a; 你分兩次發數據&#xff1a;第一次…

Docker搭建RSS訂閱服務(freshRss+rsshub)

目錄搭建freshRss1. 創建yml文件2. 創建容器3. 檢查容器狀態&#xff0c;正常運行則搭建成功4. 瀏覽器訪問并配置數據庫5. 開始使用搭建RssHub1. 創建yml文件2. 創建容器3. 檢查容器狀態&#xff0c;正常運行則搭建成功4. 瀏覽器訪問生成RSS路由&#xff08;訂閱地址&#xff0…

Spring 條件注解與 SPI 機制(深度解析)

在 Spring 及 Spring Boot 框架中&#xff0c;條件注解與 SPI 機制扮演著至關重要的角色&#xff0c;它們是實現自動配置、靈活控制 Bean 創建以及組件按需加載的關鍵所在。深入理解它們的底層實現與應用場景&#xff0c;既能幫助我們在面試中對答如流&#xff0c;又能在實際開…

Mac(二)Homebrew 的安裝和使用

官網地址&#xff1a; https://brew.sh/官方文檔&#xff1a; https://docs.brew.sh/Manpage Homebrew 是 macOS 上最強大的包管理器&#xff0c;讓你輕松安裝、更新和管理成千上萬的開發工具、命令行程序&#xff08;如 wget, tree, ffmpeg&#xff09;甚至圖形應用&#xff0…