React useMemo 深度指南:原理、誤區、實戰與 2025 最佳實踐

把“為什么用、怎么用、用錯了怎么辦”一次講透,附 React 19 自動優化前瞻


一、useMemo 是什么?

一句話:
useMemo = 記住(緩存)昂貴計算結果,只在依賴變化時重新計算。

const memoValue = useMemo(() => {return heavyCompute(a, b);
}, [a, b]);
  • 第 1 個參數:計算函數,必須返回一個值。
  • 第 2 個參數:依賴數組,React 用 Object.is 比對。
  • 返回值:緩存值,依賴不變就復用。

二、使用場景 3+1

場景示例收益
昂貴計算大數據過濾 / 排序 / 圖表計算避免每次渲染重算
穩定引用把對象/數組傳給子組件配合 React.memo 減少子組件重渲染
函數緩存返回函數時用 useCallback 語法糖防止子組件 props 變化
React 19 之前手動優化瓶頸React 19 編譯器將自動處理

三、實戰:Todo 列表性能優化

問題:每次添加 todo,都重新過濾 1000 條數據

function TodoList({ todos, filter }) {// ? 每次渲染都執行 filterTodosconst visibleTodos = filterTodos(todos, filter);return visibleTodos.map(todo => <li key={todo.id}>{todo.text}</li>);
}

解決:useMemo 緩存過濾結果

function TodoList({ todos, filter }) {const visibleTodos = useMemo(() => filterTodos(todos, filter),[todos, filter]);return visibleTodos.map(todo => <li key={todo.id}>{todo.text}</li>);
}

依賴 [todos, filter] 不變,filterTodos 只在依賴變化時運行。


四、常見誤區與對策

誤區后果對策
依賴項漏寫緩存值不更新使用 ESLint react-hooks/exhaustive-deps
過度使用緩存成本 > 計算成本先寫簡單代碼,后優化
返回函數誤用 useMemo(() => fn)改用 useCallback(fn, deps)

五、React 19 之后:還要手動用嗎?

React 19 編譯器 已能 自動記憶化

  • 大部分場景 無需手寫 useMemo/useCallback
  • 僅在 第三方庫要求引用穩定極端昂貴計算 時手動使用。

六、一鍵記憶化模板

import { useMemo } from 'react';export function useExpensiveValue<T>(factory: () => T, deps: any[]): T {return useMemo(factory, deps);
}// 用法
const data = useExpensiveValue(() => heavyCompute(a, b), [a, b]);

七、一句話總結

useMemo = “計算緩存”,只在依賴變化時重算;React 19 之前手動優化瓶頸,之后讓編譯器兜底

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

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

相關文章

[ HTML 前端 ] 語法介紹和HBuilderX安裝

目錄 一. HTML 1.概述 2. 安裝前端開發工具 (1)HBuilderX下載 (2)創建html項目和使用 3. HTML基礎 1.標簽 (1).標簽定義: (2).標簽結構: (3).標簽屬性: 2.常用標簽: 3.特殊符號: 4.表格(table) (1)基本標簽: (2)基本結構: (3)表格屬性: 5.表單(form) (1). 表單概述…

Spring Cloud系列—Alibaba Sentinel熔斷降級

上篇文章&#xff1a; Spring Cloud系列— Alibaba Sentinel限流https://blog.csdn.net/sniper_fandc/article/details/149944260?fromshareblogdetail&sharetypeblogdetail&sharerId149944260&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link…

Spring Boot 使用 @NotBlank + @Validated 優雅校驗參數

在日常開發中&#xff0c;我們常用 if (isBlank(...)) 來判斷參數是否為空&#xff0c;但這種方式不僅繁瑣&#xff0c;而且容易遺漏。 Spring 生態中推薦使用 JSR-303 校驗注解&#xff08;NotBlank、NotNull 等&#xff09;配合 Validated 實現自動校驗&#xff0c;大幅減少手…

網絡安全(Java語言)簡單腳本匯總 (一)

文章目錄敏感信息探測腳本源代碼思路URL批量存活探測器源代碼思路端口掃描器源代碼思路 敏感信息探測腳本 源代碼/*** description 該腳本通過分析HTTP響應頭&#xff0c;來檢測可能暴露服務器信息的安全隱患*/import java.io.IOException; import java.net.HttpURLConnection;…

buuctf_NSBlogin_http_upload(極客2019+ACTF2020新生賽)

今天做三1個web 題目&#xff1a;NSB_login用戶名有admin&#xff0c;看源碼&#xff1a;I like rockyou&#xff01;今天學習到&#xff0c;kali里面有密碼爆破的文件叫rockyou.txt&#xff08;/usr/share/wordlists/&#xff09;&#xff08;沒kali也可以去https://gitcode.c…

IDEA如何引用brew安裝的openjdk

因為 brew 安裝的 openjdk@21 目錄結構和 IDEA 期望的 JDK 目錄不一樣。所以默認brew安裝的jdk,在IDEA中是無法識別到的。 一、創建軟連接 sudo mkdir -p /Library/Java/JavaVirtualMachines sudo ln -sfn /usr/local/opt/openjdk@21/libexec/openjdk.jdk /Library/Java/Java…

【Unity3D】Spine黑線(預乘問題)、貼圖邊緣裁剪問題

一、黑線問題 Spine正確的導出和Unity導入設置&#xff08;解決黑邊/彩條帶問題&#xff09;_spine導出的圖片有黑邊-CSDN博客 采用&#xff08;已解決問題&#xff09; Texture 打包器啟用 Premultiply alpha ,禁用Bleed Unity Texture 設置中禁用 sRGB (Color Texture) 和…

嵌入式系統學習Day18(文件編程-系統調用文件IO)

- open#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); 功能:打開文件 參數:pathname --- 文件名 flags 必選:O_RDONLYO_WRONLY…

Vue淺學

概述在最近的學習任務中了解了 Vue&#xff0c;并對其產生了濃厚的興趣&#xff0c;現在分享一下我的學習所得關鍵字其一statestate 是 Vuex 存儲中的“狀態對象”&#xff0c;用于存儲整個應用的共享數據&#xff08;如用戶信息、令牌、權限等&#xff09;&#xff0c;比如&am…

機器翻譯:Hugging Face庫詳解

文章目錄一、Hugging Face概述1.1 Hugging Face介紹1.2 核心理念&#xff1a;模型即服務&#xff0c;但以開源形式二、核心架構2.1 Transformers庫&#xff1a;模型交互的統一接口2.2 Datasets庫&#xff1a;高效的數據處理引擎2.3 Tokenizers庫&#xff1a;文本與模型的“翻譯…

服務器安裝gielab社區版

第一步&#xff1a;安裝Gitlab 1,使用的是CentOs鏡像(服務器最低配置為4核8g內存才行要不然帶不動) 登錄目標實例。 2,執行如下命令&#xff0c;安裝所需依賴。 1 sudo yum install -y curl policycoreutils-python openssh-server 3,執行如下命令&#xff0c;啟動SSH服務…

C#報錯:System.NullReferenceException:“未將對象引用設置到對象的實例。”

C#使用自定義的類創建數組時&#xff0c;使用時報錯&#xff0c;報錯內容如下圖&#xff1a;原因&#xff1a;C#中的數組是引用類型。當聲明自定義類數組時&#xff0c;數組本身會被創建&#xff0c;但其元素&#xff08;即自定義類的實例&#xff09;默認未被實例化&#xff0…

Maven 的 module 管理

一、Maven 的 module 管理 1. 什么是 Maven module&#xff1f; Maven module&#xff08;模塊&#xff09;&#xff0c;是 Maven 多模塊項目結構&#xff08;multi-module project&#xff09;中的核心概念。它允許你將一個大型項目拆分為若干獨立的小項目&#xff08;模塊&am…

現在都是APP,小程序搶購,支持瀏覽器不支持 SSE

在 APP 和小程序搶購場景中&#xff0c;通常不原生支持SSE&#xff08;Server-Sent Events&#xff09;&#xff0c;這與瀏覽器對 SSE 的支持情況不同&#xff0c;具體如下&#xff1a;APP&#xff1a;一般情況下&#xff0c;APP 端不支持原生 SSE。若使用 UniApp 開發&#xf…

Spring Boot 深度解析:從原理到實踐

一、Spring Boot 本質與核心價值 1.1 什么是 Spring Boot&#xff1f; Spring Boot 是 Spring 生態的革命性框架&#xff0c;旨在解決傳統 Spring 開發的復雜性。它通過"約定優于配置"&#xff08;Convention Over Configuration&#xff09;理念&#xff0c;提供開箱…

WebSocket-java篇

問題引入消息推送的方式我們要實現&#xff0c;服務器把消息推送到客戶端&#xff0c;可以輪訓&#xff0c;長輪訓還有sseWebSocket理論WebSocket 的由來與核心價值誕生背景&#xff1a;解決 HTTP 協議在實時通信中的固有缺陷&#xff08;單向請求-響應模式&#xff09;核心驅動…

用Python從零開始實現神經網絡

反向傳播算法用于經典的前饋人工神經網絡。 它仍然是訓練大型深度學習網絡的技術。 在這個教程中&#xff0c;你將學習如何用Python從頭開始實現神經網絡的反向傳播算法。 完成本教程后&#xff0c;您將了解&#xff1a; 如何將輸入前向傳播以計算輸出。如何反向傳播錯誤和…

算法148. 排序鏈表

題目&#xff1a;給你鏈表的頭結點 head &#xff0c;請將其按 升序 排列并返回 排序后的鏈表 。示例 1&#xff1a;輸入&#xff1a;head [4,2,1,3] 輸出&#xff1a;[1,2,3,4] 示例 2&#xff1a;輸入&#xff1a;head [-1,5,3,4,0] 輸出&#xff1a;[-1,0,3,4,5] 示例 3&a…

在騰訊云CodeBuddy上實現一個AI聊天助手

在騰訊云CodeBuddy上實現一個AI聊天助手項目 在當今數字化時代&#xff0c;AI聊天助手已經成為一種非常流行的應用&#xff0c;廣泛應用于客戶服務、智能助手等領域。今天&#xff0c;我們將通過騰訊云CodeBuddy平臺&#xff0c;實現一個基于Spring Boot和OpenAI API的AI聊天助…

JavaScript Array.prototype.flatMap ():數組 “扁平化 + 映射” 的高效組合拳

在 JavaScript 數組處理中&#xff0c;我們經常需要先對每個元素進行轉換&#xff08;映射&#xff09;&#xff0c;再將結果 “鋪平”&#xff08;扁平化&#xff09;。比如將數組中的每個字符串按空格拆分&#xff0c;然后合并成一個新數組。傳統做法是先用map()轉換&#xf…