React学习———React.memo、useMemo和useCallback

news2025/12/15 23:45:16

React.memo

React.memo是React提供的一个高阶组件,用于优化函数组件的性能,它通过记忆组件的渲染结果,避免在父组件重新渲染时,子组件不必要的重新渲染
React.memo会对组件的props进行浅比较,如果props没有变化,则组件不会重新渲染

基本用法

import React from 'react'
const MyComponent = (props) => {
	console.log('组件渲染了')
	return <div>{props.value}</div>
}
export default React.memo(MyComponent)

工作原理

  • 默认浅比较:React.memo会对传递给组件的props进行浅比较,如果props没有变化,则跳过重新渲染
  • 自定义比较函数(可选):如果需要更复杂的比较逻辑,可以通过第二个参数传入自定义比较函数

自定义比较函数

const MyComponent = (props) => {
	console.log('组件渲染了')
	return <div>{props.value}</div>
}
const areEqual = (prevProps, nextProps) => {
	// 自定义比较逻辑
	return prevProps.value === nextProps.value
}
export default React.memo(MyComponent, areEqual)

使用场景

  • 纯函数组件:当组件的渲染结果完全依赖于props,且没有内部状态或副作用时,使用React.memo可以有效避免不必要的渲染
  • 频繁渲染的组件:在父组件频繁更新,但子组件的props变化较少的情况下,使用React.memo可以显著提升性能
  • 大型列表或复杂组件:对于渲染成本较高的组件,使用React.memo可以减少渲染次数,提升应用的整体性能

注意事项

  • 浅比较的局限性:React.memo默认使用浅比较。如果props是复杂的嵌套对象或数组,可能需要自定义比较函数
  • 状态或上下文变化:React.memo只对props的变化敏感,如果组件依赖于状态(state)或上下文(context),这些变化仍会触发重新渲染
  • 过度优化:不要滥用React.memo。因为浅比较和自定义比较函数本身也会带来一定的性能开销

useMemo

useMemo是一个React Hook,用于缓存计算结果,避免在每次渲染时重复执行耗时的计算

特点

  • 用于性能优化,减少不必要的计算
  • 只有依赖项发生变化时,才会重新计算值
  • 返回缓存的计算结果

基本用法

import React, { useMemo, useState } from 'react';
function ExpensiveCalculation(num){
	console.log('Calculating...');
	return num * 2
}
function App(){
	const [count,setCount] = useState(0)
	const [other, setOther] = useState(0);
	const result = useMemo(() => ExpensiveCalculation(count), [count])
	return (
    <div>
      <p>Result: {result}</p>
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <button onClick={() => setOther(other + 1)}>Increment Other</button>
    </div>
  );
}
export default App
  • 第一个参数:回调函数
  • 第二个参数(依赖数组):当依赖项发生变化时,useMemo会重新执行回调函数并返回新的计算结果,如果依赖项没有变化,useMemo会直接返回之前缓存的结果,而不是重新执行回调函数

注意事项

  • useMemo只会缓存计算结果,不会缓存函数本身,如果需要缓存函数本身,使用useCallback
  • 如果依赖项数组为空([]),useMemo的值只会在组件首次渲染时计算一次

useCallback

useCallback是React提供的一个Hook,用于换成函数的引用,避免在组件重新渲染时不必要的重新创建函数

基本用法

const memozedCallback = useCallback(
	() => {
		// 函数逻辑
	},
	[依赖项]
)
  • 第一个参数:需要缓存的函数
  • 第二个参数(依赖数组):当依赖项发生变化时,useCallback会返回一个新的函数引用;如果依赖项没有变化,则返回缓存的函数引用

为什么需要useCallback

  • 在React中,函数组件每次渲染都会重新创建内部的函数,如果这些函数被传递给子组件或用作依赖项,可能会导致性能问题或不必要的副作用,
  • 例如:子组件的不必要重新渲染;性能浪费,尤其在函数被频繁创建时

使用场景

  • 避免子组件不必要的重新渲染
import React, { useState, useCallback, useEffect } from 'react';
// ({onClick}):表示从props中解构出onClick的属性
// ({onClick:() => void}):为onClick属性添加类型注解,表示他是一个函数,且没有参数,返回值为void
const Child = React.memo(({onClick}:{onClick:() => void})=>{
	console.log('子组件渲染')
	return <button onClick={onClick}>点击</button>
})

function Parent(){
	const [count,setCount] = useState(0)
	
	const handleClick = useCallback(() => {
		console.log('按钮点击')
	}, [])

	return (
		<div>
			<p>计数:{count}</p>
			<button onClick={() => setCount(count+1)}>增加计数</button>
			<Child onClick={handleClick} />
		</div>
	)
}

1:未使用useCallback时,每次Parent组件重新渲染时,handleClick都会被重新创建,导致Child组件也会重新渲染
2:使用useCallback后:handleClick的引用不会改变,Child组件不会重新渲染

  • 作为依赖项传递给useEffect
import React, { useState, useCallback, useEffect } from 'react';
function Example(){
	const [count,setCount] = useState(0)
	const logCount = useCallback(() => {
		console.log(`当前计数:${count}`);
	}, [count])
	useEffect(() => {
		logCount()
	}, [logCount]) // 使用 useCallback 缓存的函数作为依赖项
	return <button onClick={() => setCount(count + 1)}>增加计数</button>;
}

1:未使用useCallback时:logCount 每次渲染都会重新创建,导致useEffect每次都重新执行
2:使用useCallback后:logCount只有在count 变化时才会更新,减少不必要的副作用

useCallback和React.memo的区别

特性useCallbackReact.memo
作用对象用于优化函数用于优化组件
核心功能避免函数在组件重新渲染时被重新创建避免组件因props未变化而重新渲染
工作原理缓存函数引用,只有依赖项变化时才重新创建浅比较props,决定是否跳过组件渲染
适用场景当函数被传递给子组件或用作依赖项时当组件的props很少变化时
性能优化的目标减少函数的重新创建次数减少组件的重新渲染次数

useCallback和React.memo结合使用

在实际开发中,经常会被结合使用,尤其是在父组件向子组件传递函数时

useMemo和React.memo的区别

特性useMemoReact.memo
作用缓存计算结果优化组件渲染,避免不必要的重新渲染
触发条件比较依赖项是否变化比较组件的props是否变化
适用场景用于函数或计算逻辑的性能优化用于组件级别的性能优化
返回值返回缓存的计算结果返回优化后的组件

总结

  • React.memo用于组件级别的性能优化,避免子组件不必要的重新渲染
  • useMemo用于缓存计算结果,适合优化耗时的计算逻辑
  • useCallback用于缓存函数引用,避免优化子组件接收函数props的场景

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2377203.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

手机换地方ip地址会变化吗?深入解析

在移动互联网时代&#xff0c;我们经常带着手机穿梭于不同地点&#xff0c;无论是出差旅行还是日常通勤。许多用户都好奇&#xff1a;当手机更换使用地点时&#xff0c;IP地址会随之改变吗&#xff1f;本文将深入解析手机IP地址的变化机制&#xff0c;帮助您全面了解这一常见但…

AI工具分享篇 | recraft.ai + figma 复刻技术路线图

recraft 介绍 recraft.ai 主要生成和编辑适合网站、印刷和营销的各种风格的矢量艺术、图标、3d图像和插图。其矢量化功能可将路线图转化为一个矢量图。 recraft 的注册流程非常的简单&#xff0c;邮箱注册即可&#xff0c;无需科学上网&#xff0c;3分钟就能搞定。看不懂英文…

部署安装jenkins.war(2.508)

实验目的&#xff1a;部署jenkins&#xff0c;并与gitlab关联bulid 所需软件&#xff1a;jdk-17_linux-x64_bin.tar.gz jenkins.war apache-tomcat-10.1.40.tar.gz 实验主机&#xff1a;8.10具有java环境,内存最少为4G&#xff0c;cpu双核 目录 jdk安装 …

JS手写代码篇---手写 Object.create

JS手写代码篇 在做手写题的时候&#xff0c;我们要思考两个问题 这个代码的作用是什么能够实现的效果是什么样子 1. 手写 Object.create 思路&#xff1a;创造一个对象&#xff0c;类似于Object.create()方法>将obj作为原型 // 手写 Object.create function create (ob…

spring boot Controller 和 RestController 的区别

spring boot Controller 和 RestController 的区别 5.3.1常用注解 Spring MVC控制器中常使用的注解有如下几种。 Controller Controller 标记在类上。使用Controller 标记的类表示是Spring MVC的Controller对象。分发处理器将会扫描使用了该注解的类&#xff0c;并检测其中的…

LeRobot 项目部署运行逻辑(七)—— ACT 在 Mobile ALOHA 训练与部署

全部流程为&#xff1a;硬件配置 -> 环境安装 -> 遥操作数据采集 -> 数据集可视化 -> 策略训练 -> 策略评估 在之前的笔记中已经完成了绝大部分&#xff0c;最后再记录一下最后的训练部署&#xff0c;算是最简单的部分了 目录 1 ACT 训练 2 ALOHA 部署 3 更…

高频交直流电流测量技术:射频PA与MEMS测试的简单解决方案

随着5G通信和智能传感器技术的快速发展&#xff0c;传统电流测量手段已难以满足现代电子设备的测试需求。最新一代交直流混合测量探头通过突破性的技术创新&#xff0c;正在重新定义射频功率器件和微机电系统的测试标准。 射频功率放大器测试新范式&#xff1a; 在5G基站等高…

原生微信小程序 textarea组件placeholder无法换行的问题解决办法

【问题描述】 微信小程序原生代码&#xff0c;使用文本域&#xff0c;placeholder使用\n 没有效果&#xff0c;网上找了一堆方案说使用 也没有效果 最后在一个前端大佬博客&#xff0c;找到解决办法&#xff0c;CSS设置word-wrap: break-word; white-space: pre-line; 【解决办…

网络协议分析 实验二 IP分片与IPv6

文章目录 索引及重要内容实验2 IP 高级实验实验2.1 IPv4协议分片实验实验2.2 IPV6协议实验2.3 ARP初级 索引及重要内容 实验2 IP 高级实验 实验2.1 IPv4协议分片实验 icmp的不可达报文 实验2.2 IPV6协议 实验2.3 ARP初级 arp –a 查看ARP缓存表内容 arp –s IP地址(格式&…

QT6 源(101)篇一:阅读与注释 QPlainTextEdit,其继承于QAbstractScrollArea,属性学习与测试

&#xff08;1&#xff09; &#xff08;2&#xff09; &#xff08;3&#xff09;属性学习与测试 &#xff1a; &#xff08;4&#xff09; &#xff08;5&#xff09; 谢谢

工业大数据的定义

目录 工业大数据的定义 工业大数据发展历程 工业大数据的特征 工业大数据的处理流程 工业大数据在处理上面临的挑战 工业大数据的有效处理方案 工业大数据处理相关案例 数益工联 x TDengine 中天钢铁 x TDengine 广州某企业工业互联网项目 x TDengine 格创东智 x TD…

126.在 Vue 3 中使用 OpenLayers 实现绘制正方形、正三角形、正五边形

🗺️ 项目效果(先看效果) 支持点击按钮绘制图形,效果如下: ✅ 正三角形 ✅ 正方形 ✅ 正五边形 ✅ 支持停止绘制 📌 前言 在 Web GIS 的实际项目中,我们经常需要绘制一些规则的图形,比如:正方形、正三角形、正五边形等,这在标注地块、规划图形、布设区域等场景中都…

3DVR制作的工具或平台

3DVR&#xff08;三维虚拟现实&#xff09;是利用三维图像技术和虚拟现实技术&#xff0c;将真实场景进行三维扫描并转换成计算机可识别的三维模型&#xff0c;使用户能够在虚拟空间中自由漫游&#xff0c;体验身临其境的感觉。3DVR技术结合了全景拍摄和虚拟现实&#xff0c;提…

高吞吐与低延迟的博弈:Kafka与RabbitMQ数据管道实战指南

摘要 本文全面对比Apache Kafka与RabbitMQ在数据管道中的设计哲学、核心差异及协同方案。结合性能指标、应用场景和企业级实战案例,揭示Kafka在高吞吐流式处理中的优势与RabbitMQ在复杂路由和低延迟传输方面的独特特点;介绍了使用Java生态成熟第三方库(如Apache Kafka Clie…

如何使用WordPress SEO检查器进行实时内容分析

在这篇文章中&#xff0c;我们将带你从头开始了解如何在WordPress中使用SEO检查工具进行实时内容分析。这篇文章面向初学者&#xff0c;帮助你理解SEO的重要性以及如何通过工具提高文章的搜索引擎优化&#xff08;SEO&#xff09;效果。 一、什么是SEO内容分析&#xff1f; 内…

C语言:深入理解指针(5)

目录 一、回调函数 二、qsort 使用举例 三、模拟qsort 一、回调函数 回调函数就是一个通过函数指针调用的函数。 举个例子&#xff1a; int Add(int x, int y) {return xy; }void test(int (*pf)(int, int)) {int r pf(10 ,20);printf("%d\n" ,r); }int main()…

IEEE出版|连续多年稳定检索|第三届信号处理与智能计算国际学术会议(SPIC2025)

【重要信息】 会议官网&#xff1a; www.ic-spic.com 会议日期&#xff1a;2025年11月28-30日 会议地点&#xff1a;中国 广州 截稿日期&#xff1a;2025年11月10日 接受或拒绝通知日期&#xff1a;提交后7个工作日 【征稿主题】 人工智能和机器学习 计算机系统和架构 …

“强强联手,智启未来”凯创未来与绿算技术共筑高端智能家居及智能照明领域新生态

近日&#xff0c;北京凯创未来科技有限公司总经理赵健凯先生莅临广东省绿算技术有限公司北京运营中心&#xff0c;双方正式签订战略合作协议&#xff0c;标志着绿算技术在高端智能家居及智能照明领域的技术实力与产业布局获得智能家居行业认可&#xff0c;同时也为凯创未来在高…

MQ消息队列的深入研究

目录 1、Apache Kafka 1.1、 kafka架构设 1.2、最大特点 1.3、功能介绍 1.4、Broker数据共享 1.5、数据一致性 2、RabbitMQ 2.1、架构图 2.2、最大特点 2.3、工作原理 2.4、功能介绍 3、RocketMQ 3.1、 架构设计 3.2、工作原理 3.3、最大特点 3.4、功能介绍 3…

【NLP 74、最强提示词工程 Prompt Engineering 从理论到实战案例】

一定要拼尽全力&#xff0c;才能看起来毫不费劲 —— 25.5.15 一、提示词工程 1.提示词工程介绍 Ⅰ、什么是提示词 所谓的提示词其实就是一个提供给模型的文本片段&#xff0c;用于指导模型生成特定的输出或回答。提示词的目的是为模型提供一个任务的上下文&#xff0c;以便模…