React.memo 和 useMemo

現象

React 中,通常父組件的某個state發生改變,會引起父組件的重新渲染(和其他state的重新計算),從而會導致子組件的重新渲染(和其他非相關屬性的重新計算)

  • 問題一:如何避免因為某個state變化,導致組件的中其他屬性(state)的重新計算?

? ? ? ?方案:useMemo

  • 問題二:如何避免因為父組件的重新渲染,導致子組件中非相關屬性的重新計算?

? ? ? ?方案:React.memo

結論

總結起來就一句話:

React.memo 用來限制組件重新渲染,而 useMemo?用來限制組件中的部分變量重新計算

(前者主要針對組件的渲染,后者則側重于組件內的計算)

示例

React.memo:【常用于子組件】

它是一個高階組件(Higher-Order Component,HOC),用于包裝函數組件

當父組件重新渲染時,往往會觸發子組件的重新渲染。但很多時候子組件的?props?并沒有改變,此時子組件的重新渲染就是不必要的,會造成性能浪費。

經過?React.memo?包裝的組件,React 會對其?props?進行淺比較,如果新?props?和舊?props?相同,組件不會重新渲染,而是復用之前的渲染結果。(淺比較只會檢查對象或數組的引用是否相同,而不會深入比較其內部的屬性或元素)

import React from 'react';// 使用 React.memo 包裹組件
const MyComponent = React.memo(({ data }) => {console.log('組件重新渲染');return <div>{data}</div>;
});const ParentComponent = () => {const [count, setCount] = React.useState(0);const someData = '固定數據';return (<div>{/* 如果子組件不用React.memo包裹,count變化后子組件也會重新渲染 */}<button onClick={() => setCount(count + 1)}>增加計數</button>{/* 只要 someData 不變,MyComponent 不會重新渲染 */}<MyComponent data={someData} /></div>);
};export default ParentComponent;

useMemo

這是一個 React Hook,只能用于函數組件內部

它主要用于緩存計算結果,根據傳入的依賴項數組來判斷是否需要重新計算緩存的值,避免在每次組件渲染時都進行重復的高開銷計算。

如果計算屬性作為子組件的?props?傳遞,且子組件使用?React.memo?進行了優化,在父組件使用?useMemo?可以確保計算屬性的引用在依賴項不變時保持穩定,從而避免子組件不必要的重新渲染。

import React, { useState, useMemo, memo } from 'react';const ChildComponent = memo(({ data }) => {console.log('ChildComponent rendered');return <div>{data}</div>;
});const ParentComponent = () => {const [num, setNum] = useState(1);const calculatedData = useMemo(() => {return num * 2;}, [num]);return (<div><inputtype="number"value={num}onChange={(e) => setNum(Number(e.target.value))}/><ChildComponent data={calculatedData} /></div>);
};export default ParentComponent;

這里?calculatedData?通過?useMemo?緩存,當?num?不變時,calculatedData?的引用保持不變,ChildComponent?不會因為?props?的引用變化而重新渲染。

順便提一下【useCallback】:

當父組件向子組件傳遞一個函數作為?props,并且子組件使用?React.memo?包裹時,useCallback?可以確保該函數的引用在依賴項不變時保持穩定,從而避免子組件因為函數引用的改變而進行不必要的重新渲染。

import React, { useState, useCallback, memo } from 'react';// 使用 React.memo 包裹子組件
const ChildComponent = memo(({ onClick }) => {console.log('ChildComponent 渲染');return <button onClick={onClick}>點擊我</button>;
});const ParentComponent = () => {const [count, setCount] = useState(0);// 使用 useCallback 緩存函數const handleClick = useCallback(() => {setCount(count + 1);}, [count]);return (<div><p>計數: {count}</p><ChildComponent onClick={handleClick} /></div>);
};export default ParentComponent;

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

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

相關文章

防火墻技術深度解析:從包過濾到云原生防火墻的部署與實戰

防火墻技術深度解析&#xff1a;從包過濾到云原生防火墻的部署與實戰 在網絡安全防御體系中&#xff0c;防火墻是第一道物理屏障&#xff0c;承擔著“網絡流量守門人”的核心角色。從早期基于IP地址的包過濾設備到如今集成AI威脅檢測的云原生防火墻&#xff0c;其技術演進始終…

strcmp()在C語言中怎么用(附帶實例)

C語言標準庫中的 strcmp() 函數用于比較兩個字符串。 strcmp() 函數原型如下&#xff1a; int strcmp (const char * str1, const char * str2); const char *str1 表示待比較字符串 1 的首地址&#xff1b;const char *str2 表示待比較字符串 2 的首地址。 如果兩個字符串相…

搜廣推校招面經八十二

一、L1 和 L2 正則化的區別&#xff1f;對數據分布有什么要求&#xff0c;它們都能防止過擬合嗎&#xff1f; 1.1. L1 與 L2 正則化的區別 特性L1 正則化&#xff08;Lasso&#xff09;L2 正則化&#xff08;Ridge&#xff09;正則項λ * ∑|w?| λ ? ∑ ( w i 2 ) λ * ∑…

數據結構和算法(九)--紅黑樹

一、紅黑樹 1、紅黑樹 前面介紹了2-3樹&#xff0c;可以看到2-3樹能保證在插入元素之后&#xff0c;樹依然保持平衡狀態&#xff0c;它的最壞情況下所有子結點都是2-結點&#xff0c;樹的高度為IgN&#xff0c;相比于我們普通的二叉查找樹&#xff0c;最壞情況下樹的高度為N,確…

工業攝像頭通過USB接口實現圖像

工業攝像頭系列概覽&#xff1a;類型與應用 工業攝像頭系列涵蓋了多種類型&#xff0c;以滿足不同行業和應用的需求。以下是對工業攝像頭系列的一些介紹&#xff1a; 一、主要類型與特點 USB工業攝像頭 &#xff1a;這類攝像頭通常通過USB接口與計算機連接&#xff0c;適用于…

使用Django框架表單

使用Django框架表單 文章目錄 使用Django框架表單[toc]1.使用Form類構建表單2.表單字段與Widget控件 1.使用Form類構建表單 【創建項目和應用】 PS C:\Users\ls> cd E:\Python\ PS E:\Python> django-admin.exe startproject FormSite PS E:\Python> cd .\FormSite\…

docker配置mysql遇到的問題:網絡連接超時、啟動mysql失敗、navicat無法遠程連接mysql

目錄 1.網絡超時 方式1. 網絡連接問題 方式2. Docker鏡像源問題 方式3.使用國內鏡像源 2.啟動mysql鏡像失敗 3.navicat無法遠程連接mysql 1.網絡超時 安裝MySQL時出現超時問題&#xff0c;可能由多種原因導致&#xff1a; 方式1. 網絡連接問題 原因&#xff1a;網絡不穩定…

React 多語言國際化:實現多語言支持

&#x1f90d; 前端開發工程師、技術日更博主、已過CET6 &#x1f368; 阿珊和她的貓_CSDN博客專家、23年度博客之星前端領域TOP1 &#x1f560; 牛客高級專題作者、打造專欄《前端面試必備》 、《2024面試高頻手撕題》、《前端求職突破計劃》 &#x1f35a; 藍橋云課簽約作者、…

Claude系列模型-20250426

文章目錄 Claude 3.7 Sonnet - "Our most intelligent model yet"Claude 3.5 Haiku - "Fastest model for daily tasks"Claude 3.5 Sonnet (Oct 2024)Claude 3 Opus總結Claude 3.7 Sonnet - “Our most intelligent model yet” 特點: 這是目前Claude系列…

Linux查看可用端口號碼命令

在Linux系統中&#xff0c;有多種命令可用于查看可用端口號碼&#xff0c;下面為你詳細介紹&#xff1a; 1. 使用netstat命令 netstat是一個功能強大的網絡工具&#xff0c;可用于顯示網絡連接、路由表和網絡接口等信息。你可以結合不同的選項來查看端口使用情況。 查看所有…

leetcode201.數字范圍按位與

找到公共前綴部分&#xff0c;然后后面的部分全0 class Solution {public int rangeBitwiseAnd(int left, int right) {int offset 0;while (left ! right) {offset;left left >> 1;right right >> 1;}return right << offset;} }

端到端自動駕駛的數據規模化定律

25年4月來自Nvidia、多倫多大學、NYU和斯坦福大學的論文“Data Scaling Laws for End-to-End Autonomous Driving”。 自動駕駛汽車 (AV) 棧傳統上依賴于分解方法&#xff0c;使用單獨的模塊處理感知、預測和規劃。然而&#xff0c;這種設計在模塊間通信期間會引入信息丟失&am…

021-C語言文件操作

C語言文件操作 文章目錄 C語言文件操作1. 文件的概念2. 二進制文件和文本文件3. 文件的打開和關閉3.1 流和標準流3.1.1 流3.1.2 標準流 3.2 文件指針3.3 文件的打開和關閉 4. 文件的順序讀寫4.1 順序讀寫函數4.2 對比兩組函數4.2.1 scanf/fscanf/sscanf4.2.2 printf/fprintf/sp…

如何使用@KafkaListener實現從nacos中動態獲取監聽的topic

1、簡介 對于經常需要變更kafka主題的場景&#xff0c;為了實現動態監聽topic的功能&#xff0c;可以使用以下方式。 2、使用步驟 2.1、添加依賴 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactI…

《TCP/IP詳解 卷1:協議》之第七、八章:Ping Traceroute

目錄 一、ICMP回顯請求和回顯應答 1、ICMP回顯請求 2、ICMP回顯應答 二、ARP高速緩存 三、IP記錄路由選項&#xff08;Record Route&#xff0c;RR&#xff09; 1、記錄路由選項的工作過程 2、RR 選項的 IP 頭部格式 2.1、RR 請求 2.2、RR響應 四、ping 的去返路徑 五…

30天通過軟考高項-第四天

30天通過軟考高項-第四天 任務&#xff1a;項目進度管理 思維導圖閱讀 知識點集錦閱讀 知識點記憶 章節習題練習 知識點練習 手寫回憶ITTO 聽一遍喜馬拉雅關于范圍的內容 進度管理-背 1. 過程定義 龜腚排池至控 規劃進度管理&#xff1a;為了規劃、編制、管理…

根據JSON動態生成表單表格

根據JSON動態生成表單表格 一. 子組件 DynamicFormTable.vue1,根據JSON數據動態生成表單表格,支持表單驗證JS部分1.1,props數據1.2,表單數據和數據監聽1.3,自動驗證1.4,表單驗證1.5,獲取表單數據1.6,事件處理1.7,暴露方法給父組件2,HTML部分二,父組件1, 模擬數據2,…

【趙渝強老師】快速上手TiDB數據庫

從TiDBv4.0起&#xff0c;提供了包管理工具TiUP&#xff0c;負責管理TiDB、PD、TiKV等組件。用戶只需通過TiUP命令即可運行這些組件&#xff0c;顯著降低了管理難度。TiUP程序只包含少數幾個命令&#xff0c;用來下載、更新、卸載組件。TiUP通過各種組件來擴展其功能。組件是一…

springboot入門-DTO數據傳輸層

在 Spring Boot 應用中&#xff0c;DTO&#xff08;Data Transfer Object&#xff0c;數據傳輸對象&#xff09; 是專門用于在不同層&#xff08;如 Controller 層、Service 層、外部系統&#xff09;之間傳輸數據的對象。它的核心目的是解耦數據模型和業務邏輯&#xff0c;避免…

安裝docker,在docker上安裝mysql,docker上安裝nginx

目錄 一.安裝docker 1.1查看Linux版本的命令這里推薦兩種&#xff1a; 1.2查看內核版本有三種方式&#xff1a; 2.安裝 2.1 如果之前安裝了docker&#xff0c;先刪除舊版本的doker 2.2 安裝需要的軟件包&#xff0c;yum-util提供yum-config-manager功能&#xff0c;另外兩…