当前位置: 首页 > news >正文

WHAT - React 函数与 useMemo vs useCallback

目录

  • 一、介绍
    • `useMemo` 与 `useCallback` 的区别
    • 示例代码
      • `useMemo` 示例
      • `useCallback` 示例
    • 总结
  • 二、当一个函数被作为依赖项
    • `useMemo` 和 `useCallback` 的适用情况
    • 选择使用 `useCallback` 或 `useMemo`
    • 总结
    • 实际例子

一、介绍

在 React 中,useMemouseCallback 是两个用于性能优化的钩子,尽管它们有些相似,但各自有不同的用途和应用场景。理解它们的区别和适用情况可以帮助你更有效地管理组件的性能和状态。

useMemouseCallback 的区别

  1. useMemo:

    • 目的: 用于记忆化(缓存)计算结果。它接受一个计算函数和依赖项数组,只有当依赖项发生变化时,计算函数才会重新执行。
    • 用法: 当你需要避免在每次渲染时重复计算一个值时使用。比如,当计算一个复杂的值(如列表过滤、排序)时,可以使用 useMemo 来缓存计算结果,避免不必要的重新计算。
    • 语法:
      const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
      
  2. useCallback:

    • 目的: 用于记忆化(缓存)函数。它接受一个函数和依赖项数组,只有当依赖项发生变化时,函数才会重新创建。
    • 用法: 当你需要避免在每次渲染时重新创建一个函数,尤其是当函数作为 props 传递给子组件时,使用 useCallback 可以确保子组件不因函数的重新创建而重新渲染。
    • 语法:
      const memoizedCallback = useCallback(() => {// Your callback logic
      }, [dependencies]);
      

示例代码

useMemo 示例

假设你有一个计算密集型的函数 computeExpensiveValue,它依赖于 ab

import React, { useMemo, useState } from 'react';const ExpensiveComponent = ({ a, b }) => {// 使用 useMemo 缓存计算结果const result = useMemo(() => computeExpensiveValue(a, b), [a, b]);return <div>{result}</div>;
};function computeExpensiveValue(a, b) {// 假设这个函数很复杂console.log('Computing expensive value...');return a + b;
}

在这个示例中,computeExpensiveValue 只会在 ab 改变时重新计算,否则会返回缓存的结果。

useCallback 示例

假设你有一个处理点击事件的函数 handleClick,它被传递给子组件 ButtonComponent

import React, { useCallback, useState } from 'react';const ParentComponent = () => {const [count, setCount] = useState(0);// 使用 useCallback 缓存函数const handleClick = useCallback(() => {setCount(count + 1);}, [count]);return <ButtonComponent onClick={handleClick} />;
};const ButtonComponent = ({ onClick }) => {console.log('ButtonComponent rendered');return <button onClick={onClick}>Click me</button>;
};

在这个示例中,handleClick 只会在 count 改变时重新创建,从而避免不必要的子组件重新渲染。

总结

  • useMemo: 用于缓存计算结果。适用于复杂计算、渲染时计算。
  • useCallback: 用于缓存函数。适用于避免函数重新创建,尤其是当函数作为 props 传递给子组件时。

选择使用 useMemo 还是 useCallback 取决于你的具体需求。如果你需要记忆化计算结果,使用 useMemo;如果你需要记忆化函数,使用 useCallback。通常,它们可以结合使用,以优化性能和避免不必要的渲染或计算。

二、当一个函数被作为依赖项

当你有一个函数被用作依赖项时,是否应该使用 useMemo 还是 useCallback 来封装它,取决于你的具体情况。下面是关于这两种钩子的详细指南,以帮助你做出决定:

useMemouseCallback 的适用情况

  1. useCallback:

    • 用途: 用于缓存函数的实例。它创建一个稳定的函数引用,只有当其依赖项发生变化时,才会重新创建该函数。

    • 使用场景:

      • 当你需要将函数传递给子组件作为 props,以避免子组件因为函数引用变化而重新渲染。
      • 当你需要确保函数在依赖项变化时保持稳定。
    • 示例:

      import React, { useCallback, useState } from 'react';const ParentComponent = () => {const [count, setCount] = useState(0);// 使用 useCallback 缓存函数const handleClick = useCallback(() => {setCount(count + 1);}, [count]); // 依赖项为 countreturn <ChildComponent onClick={handleClick} />;
      };const ChildComponent = ({ onClick }) => {console.log('ChildComponent rendered');return <button onClick={onClick}>Click me</button>;
      };
      
  2. useMemo:

    • 用途: 用于缓存计算结果。它记忆化计算结果,只有在依赖项发生变化时,才会重新计算。

    • 使用场景:

      • 当你有一个计算密集型的操作,且希望避免每次渲染都进行重复计算。
      • 当你需要缓存某个值而不是函数,以减少计算量。
    • 示例:

      import React, { useMemo, useState } from 'react';const ParentComponent = ({ items }) => {// 使用 useMemo 缓存计算结果const sortedItems = useMemo(() => {return [...items].sort(); // 假设这是一个耗时的排序操作}, [items]); // 依赖项为 itemsreturn <ChildComponent items={sortedItems} />;
      };const ChildComponent = ({ items }) => {return (<ul>{items.map((item, index) => (<li key={index}>{item}</li>))}</ul>);
      };
      

选择使用 useCallbackuseMemo

  • 函数作为依赖项: 如果你有一个函数作为依赖项,并且你希望这个函数的引用在组件的生命周期中保持稳定,使用 useCallback 是合适的。例如,如果你将这个函数作为 props 传递给子组件,useCallback 可以确保子组件不会因为函数引用的变化而重新渲染。

  • 计算结果作为依赖项: 如果你希望缓存一个值的计算结果,而这个值的计算依赖于某些状态或属性,使用 useMemo 是合适的。例如,如果你有一个计算密集型的值需要在依赖项变化时重新计算,但希望在依赖项没有变化时返回缓存的结果。

总结

  • 使用 useCallback: 当你需要稳定的函数引用,尤其是当这个函数作为依赖项或传递给子组件时。
  • 使用 useMemo: 当你需要缓存计算结果,以避免重复的计算操作。

实际例子

假设你有一个函数 fetchData 被用作依赖项,在 useEffect 中:

import React, { useEffect, useCallback } from 'react';const MyComponent = ({ fetchData }) => {// 假设你在 useEffect 中使用 fetchDatauseEffect(() => {fetchData(); // 只在 fetchData 变化时调用}, [fetchData]);// 使用 useCallback 缓存 fetchData(如果需要稳定性)const memoizedFetchData = useCallback(fetchData, [fetchData]);return <div>Content</div>;
};export default MyComponent;

在这个例子中,useCallback 用于确保 fetchData 函数的稳定引用。如果 fetchData 是从 props 中传递进来的,你可以使用 useCallback 来缓存它的引用。

总的来说,选择 useMemo 还是 useCallback 取决于你是否在意函数的稳定性还是计算结果的稳定性。

相关文章:

WHAT - React 函数与 useMemo vs useCallback

目录 一、介绍useMemo 与 useCallback 的区别示例代码useMemo 示例useCallback 示例 总结 二、当一个函数被作为依赖项useMemo 和 useCallback 的适用情况选择使用 useCallback 或 useMemo总结实际例子 一、介绍 在 React 中&#xff0c;useMemo 和 useCallback 是两个用于性能…...

系统分析师7:数学与经济管理

文章目录 1 图论应用1.1 最小生成树1.2 最短路径1.3 网络与最大流量 2 运筹方法2.1 线性规划2.2 动态规划2.2.1 供需平衡问题2.2.2 任务指派问题 3 预测与决策3.1 不确定型决策分析3.2 风险型决策3.2.1 决策树3.2.2 决策表 4 随机函数5 数学建模 1 图论应用 ①最小生成树 连接…...

一套简约的qt 蓝色qss方案

一套简约的qt 蓝色qss方案 直接使用qss代码 QMenu {background: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 rgba(255, 255, 255, 240),stop:0.2 rgba(255, 255, 255, 200),stop:0.6 rgba(255, 255, 255, 160),stop:1 rgba(255, 255, 255, 120));qproperty-effect: blur…...

OCSP原理及实践

1.OCSP介绍 在PKI体系中&#xff0c;CA机构颁发合法的证书。使用者可以使用CA根证书验证该证书是否被篡改过&#xff0c;但无法从证书文件验证出证书是否被吊销。因此CA机构会通过发布CRL&#xff08;Certificate Revocation List&#xff09;来告知所有人&#xff0c;哪些证书…...

前端流程图框架

1、Mermaid&#xff1a; Mermaid 是一个用于绘制流程图、时序图、甘特图等的纯 JavaScript 库。它使用简单的文本语法来定义图表结构&#xff0c;支持多种类型的流程图&#xff0c;易于集成到网页中。 2、Draw.io&#xff1a; Draw.io 是一个在线的流程图绘制工具&#xff0…...

13.6 编写go代码接收webhook的告警发送钉钉

本节重点介绍 : 使用钉钉机器人发送到钉钉群通过alertmanager webhook发送我们自定义的go程序中解析alert对象并拼接钉钉信息发送 需求分析 使用钉钉机器人发送到钉钉群 钉钉机器人发送群消息 文档地址 通过webhook发送我们自定义的go程序中 然后解析发过来的alert&#x…...

codetest

1、寻找身高相近的小朋友 #include <iostream> #include <bits/stdc.h>using namespace std;//寻找身高相近的小朋友//输入&#xff0c;第一行两个整数&#xff0c;分别是小明身高&#xff0c;其他小伙伴个数&#xff0c;第二行是其他小伙伴的身高 //100 10 //95 …...

MyBatis-Plus拦截器接口InnerInterceptor失效?因MyBatis缓存机制而踩的一个深坑

InnerInterceptor 接口是 MyBatis-Plus 提供的一个拦截器接口&#xff0c;用于实现一些常用的 SQL 处理逻辑。例如某个组件运作在多系统的平台上&#xff0c;不同系统需要隔离&#xff0c;于是可以通过这个拦截器接口&#xff0c;给每一条要执行的sql末尾拼接一个AND systemId …...

jmeter之计数器

计数器作用&#xff1a; 对于自增长的数字&#xff0c;可以使用计数器实现 一、添加计数器及参数说明 添加计数器 计数器参数说明 Starting value&#xff1a;给定计数器的起始值、初始值&#xff0c;第一次迭代时&#xff0c;会把该值赋给计数器 递增&#xff1a;每次迭代…...

协议集合(学习笔记)

按照数据的传送方式&#xff0c;通信协议可分为以下2种。 串行通信&#xff1a;串行&#xff08;Serial&#xff09;指的是逐个传输数据位&#xff0c;一次只传输一个位。 并行通信&#xff1a;并行&#xff08;Parallel&#xff09;指的是同时传输多个数据位&#xff0c;一次…...

进程

进程 进程进程的含义PCB块内存空间进程分类&#xff1a;进程的作用进程的状态进程已经准备好执行&#xff0c;所有的资源都已分配&#xff0c;只等待CPU时间进程的调度 进程相关命6.查询进程相关命令1.ps aux2.top3.kill和killall发送一个信号 函数1.fork();2.getpid3.getppid示…...

10款好用的电脑监控软件推荐丨2024年干货整理,赶紧码住!

选择合适的电脑监控软件可以帮助企业和个人更好地管理和保护其计算机资源。以下是10款较为好用的电脑监控软件推荐。 1. 安企神 7天试用体验https://work.weixin.qq.com/ca/cawcde06a33907e60a 简介&#xff1a;安企神是一款专为企业设计的信息安全管理软件&#xff0c;提供…...

【MySQL-24】万字全面解析<索引>——【介绍&语法&性能分析&使用规则】

前言 大家好吖&#xff0c;欢迎来到 YY 滴MySQL系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Lin…...

刷题记录(2)

1. HWOD机试 - 模拟消息队列(100) package com.yue.test;import org.junit.Test;import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List;/*** Author: 夜雨* Date: 2021-12-08-10:31* Description:* Version 1.0*/ public…...

JVM中的GC过程

堆内存结构&#xff1a;在详细讨论GC过程之前&#xff0c;需要了解JVM堆内存的结构。JVM堆内存通常被分为新生代&#xff08;Young Generation&#xff09;和老年代&#xff08;Old Generation&#xff09;&#xff0c;其中新生代又进一步细分为Eden区&#xff08;Eden Space&a…...

Python实战项目:天气数据爬取+数据可视化(完整代码)_python爬虫实战

一、选题的背景 随着人们对天气的关注逐渐增加&#xff0c;天气预报数据的获取与可视化成为了当今的热门话题&#xff0c;天气预报我们每天都会关注&#xff0c;天气情况会影响到我们日常的增减衣物、出行安排等。每天的气温、相对湿度、降水量以及风向风速是关注的焦点。通过…...

FFmpeg源码:compute_frame_duration函数分析

一、compute_frame_duration函数的定义 compute_frame_duration函数定义在FFmpeg源码&#xff08;本文演示用的FFmpeg源码版本为7.0.1&#xff09;的源文件libavformat/demux.c中&#xff1a; /*** Return the frame duration in seconds. Return 0 if not available.*/ stat…...

ARM 异常处理(21)

异常的流程&#xff1a; 首先&#xff1a; 在硬件上阶段&#xff1a; 这里是4大步3小步 然后是 异常处理&#xff1a; 这里主要是保存现场&#xff0c;进行异常处理 然后是 异常返回&#xff1a; 主要指 恢复现场&#xff0c; 再跳转回去。 首先硬件上&#xff…...

我开源了我的新闻网站项目

&#x1f389; 前言 暑假时写了一个Web项目&#xff0c;感觉做的还是有模有样的&#xff0c;不仅做了前端&#xff0c;还加了后端并连了数据库。最近也是将它开源了&#xff0c;一来是为了熟悉一下Github流程和Git使用命令&#xff0c;二来也是想和大家分享一下自己的成果&…...

LlamaIndex 使用 RouterOutputAgentWorkflow

LlamaIndex 中提供了一个 RouterOutputAgentWorkflow 功能&#xff0c;可以集成多个 QueryTool&#xff0c;根据用户的输入判断使用那个 QueryEngine&#xff0c;在做查询的时候&#xff0c;可以从不同的数据源进行查询&#xff0c;例如确定的数据从数据库查询&#xff0c;如果…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...

微服务通信安全:深入解析mTLS的原理与实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言&#xff1a;微服务时代的通信安全挑战 随着云原生和微服务架构的普及&#xff0c;服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

uni-app学习笔记三十五--扩展组件的安装和使用

由于内置组件不能满足日常开发需要&#xff0c;uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件&#xff0c;需要安装才能使用。 一、安装扩展插件 安装方法&#xff1a; 1.访问uniapp官方文档组件部分&#xff1a;组件使用的入门教程 | uni-app官网 点击左侧…...

命令行关闭Windows防火墙

命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)​方法二:CMD命令…...

2.2.2 ASPICE的需求分析

ASPICE的需求分析是汽车软件开发过程中至关重要的一环&#xff0c;它涉及到对需求进行详细分析、验证和确认&#xff0c;以确保软件产品能够满足客户和用户的需求。在ASPICE中&#xff0c;需求分析的关键步骤包括&#xff1a; 需求细化&#xff1a;将从需求收集阶段获得的高层需…...

深度解析:etcd 在 Milvus 向量数据库中的关键作用

目录 &#x1f680; 深度解析&#xff1a;etcd 在 Milvus 向量数据库中的关键作用 &#x1f4a1; 什么是 etcd&#xff1f; &#x1f9e0; Milvus 架构简介 &#x1f4e6; etcd 在 Milvus 中的核心作用 &#x1f527; 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...

接口 RESTful 中的超媒体:REST 架构的灵魂驱动

在 RESTful 架构中&#xff0c;** 超媒体&#xff08;Hypermedia&#xff09;** 是一个核心概念&#xff0c;它体现了 REST 的 “表述性状态转移&#xff08;Representational State Transfer&#xff09;” 的本质&#xff0c;也是区分 “真 RESTful API” 与 “伪 RESTful AP…...