【useCallback Hook】在多次渲染中缓存组件中的函数,避免重复创建函数

news2025/1/25 3:42:16

文章目录

    • 什么是 useCallback?
      • 基本语法
    • 为什么需要 useCallback?
    • 示例
      • 1. 避免子组件重复创建函数
      • 2. 作为 useEffect 的依赖项
    • 注意事项
    • 总结

在 React 开发中,性能优化是一个重要的主题。随着应用规模的增长,组件的重新渲染可能会变得频繁,从而影响应用的性能。useCallback 是 React 提供的一个 Hook,用于返回一个记忆化的回调函数。它可以帮助我们在依赖项没有变化的情况下,避免函数的重新创建,从而减少不必要的子组件重新渲染。本文将详细介绍 useCallback 的工作原理、使用场景以及如何正确使用它。

什么是 useCallback?

useCallback 是 React 提供的一个 Hook,用于返回一个记忆化的回调函数。它可以帮助我们在依赖项没有变化的情况下,避免函数的重新创建,从而减少不必要的子组件重新渲染。

基本语法

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);
  • 回调函数:第一个参数是要记忆化的函数。
  • 依赖项数组:第二个参数是一个数组,包含所有在回调函数中使用的外部变量。只有当这些变量发生变化时,useCallback 才会返回一个新的函数。

为什么需要 useCallback?

在 React 中,每当父组件重新渲染时,子组件也会重新渲染,即使子组件的 props 没有变化。这是因为每次父组件重新渲染时,都会创建新的函数实例。如果子组件依赖于这些函数,即使这些函数的逻辑没有变化,子组件也会认为 props 发生了变化,从而重新渲染。

示例

1. 避免子组件重复创建函数

// Parent.tsx
import React, { useState, useCallback } from "react";
import Child from './Child';

const Child = React.memo(({ onClick }) => {
  console.log("Child component rendered");
  return <button onClick={onClick}>Click me</button>;
});

function Parent() {
  const [count, setCount] = useState(0);

  // 使用 useCallback 缓存回调函数
  const handleClick = useCallback(() => {
    console.log("Button clicked");
  }, []); // 空依赖项数组表示回调函数不会变化

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <Child onClick={handleClick} />
    </div>
  );
}

export default Parent;

解释:

  • Child 组件使用了 React.memo,只有当它的 props 发生变化时才会重新渲染。
  • handleClick 通过 useCallback 缓存,因此即使 Parent 组件重新渲染,Child 也不会因为 onClick 的变化而重新渲染。

2. 作为 useEffect 的依赖项

// App.tsx
import { useState, useEffect, useCallback } from "react";

function App() {
  const [count, setCount] = useState(0);
  const [page, setPage] = useState(1)

  // 使用 useCallback 缓存回调函数
  const fetchData = useCallback(() => {
    console.log("Fetching data...");
  }, [page]); // page 变化时重新创建回调函数

  useEffect(() => {
    console.log("useEffect called")
    fetchData();
  }, [fetchData]); // 将 fetchData 作为依赖项

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <button onClick={() => setPage(page + 1)}>page + 1</button>
    </div>
  );
}

export default App;

解释:

  • fetchData 通过 useCallback 缓存,因此即使组件重新渲染,useEffect 也不会因为 fetchData 的变化而重新执行。

注意事项

  1. 不要滥用 useCallback:

    • 如果函数非常简单,或者不需要传递给子组件,使用 useCallback 可能会增加额外的开销,反而降低性能。
    • 只有在确实需要缓存函数时才使用 useCallback
  2. 依赖项数组:

    • 确保依赖项数组包含所有在回调函数中使用的外部变量,否则可能会导致闭包问题(例如使用过期的状态或 props)。
  3. 与 React.memo 结合使用:

    • useCallback 通常与 React.memo 一起使用,以避免子组件的不必要渲染。

总结

useCallback 是一个用于缓存回调函数的 Hook,主要用途是优化性能,避免不必要的函数重新创建和子组件重新渲染。它的核心思想是在依赖项不变的情况下返回同一个函数引用。正确使用 useCallback 可以显著提升 React 应用的性能,尤其是在需要传递回调函数给子组件的场景中。

希望这篇博客能够帮助你深入理解 useCallback 的工作原理和使用方法!如果有任何问题或建议,欢迎在评论区留言。

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

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

相关文章

隐私保护+性能优化,RyTuneX 让你的电脑更快更安全

RyTuneX 是一款专为 Windows 10 和 11 用户量身打造的系统优化工具&#xff0c;采用先进的 WinUI 3 框架开发&#xff0c;以其现代化的设计风格和强大的功能集合脱颖而出。这款工具不仅界面简洁美观&#xff0c;还提供了多样化的系统优化选项&#xff0c;旨在帮助用户最大化设备…

JAVA:Spring WebClient 的应用指南

1、简述 随着微服务架构的普及&#xff0c;服务间的 HTTP 通信需求也越来越多。Spring 提供的 WebClient 是 RestTemplate 的替代方案&#xff0c;支持响应式编程&#xff0c;具有非阻塞的特点&#xff0c;非常适合处理高并发的 HTTP 请求。本文将介绍 WebClient 的基本用法及…

如何给自己的域名配置免费的HTTPS How to configure free HTTPS for your domain name

今天有小伙伴给我发私信&#xff0c;你的 https 到期啦 并且随手丢给我一个截图。 还真到期了。 javapub.net.cn 这个网站作为一个用爱发电的编程学习网站&#xff0c;用来存编程知识和面试题等&#xff0c;平时我都用业余时间来维护&#xff0c;并且还自费买了服务器和阿里云…

深度学习 Pytorch 动态计算图与梯度下降入门

在上节末尾我们发现autograd.grad函数可以灵活进行函数某一点的导数和偏导数的运算&#xff0c;但微分运算只是AutoGrad模块中的一小部分功能&#xff0c;本节将继续讲解这个模块的其他常用功能&#xff0c;并在此基础上介绍另一个常用优化算法&#xff1a;梯度下降算法。 imp…

gitlab使用多数据库

1. 说明 默认情况下&#xff0c;GitLab 使用一个单一的应用数据库&#xff0c;称为主数据库。为了扩展 GitLab&#xff0c;您可以将 GitLab 配置为使用多个应用数据库。 设置多个数据库后&#xff0c;GitLab 将使用第二个应用数据库用于 CI/CD 功能&#xff0c;称为 CI 数据库…

Docker网段和服务器ip冲突导致无法访问网络的解决方法

若宿主机所在网络的网段为172.[17-31].xx.xx&#xff0c;则会与Docker本身内部网络间出现冲突&#xff0c;此时需要重新配置Docker默认地址池 一&#xff1a;查看docker的默认网段 route 二&#xff1a;修改docker的默认网段 etc/docker/daemon.json文件增加修改网段信息 {…

HTML<img>标签

例子 如何插入图片&#xff1a; <img src"img_girl.jpg" alt"Girl in a jacket" width"500" height"600"> 下面有更多“自己尝试”的示例。 定义和用法 该<img>标签用于在 HTML 页面中嵌入图像。 从技术上讲&#x…

leetcode_3092. 最高频率的 ID

https://leetcode.cn/problems/most-frequent-ids/description/ 看到这个数据范围 最极端情况 如果nums全为一个数 并且数量取到最大 那么范围是10的10次方 需要longlong储存 这题主要运用了哈希表配合multiset实现 哈希表主要用作存储某个数的出现次数 mst则用于记录出现次…

01学习nodejs的准备工作

01学习nodejs的准备工作 1.回顾与思考1.1为什么JavaScript可以在浏览器中被执行1.2为什么JavaScript可以操作DOM和BOM&#xff1f;1.3浏览器中的JavaScript运行环境1.4JavaScript 能否做后端开发 2.Nodejs简介2.1什么是nodejs2.2 Node.js中的 JavaScript 运行环境2.3 Node.js可…

2024年度总结-CSDN

2024年CSDN年度总结 Author&#xff1a;OnceDay Date&#xff1a;2025年1月21日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 文章目录 2024年CSDN年度总结1. 整体回顾2…

2024年度技术总结——MCU与MEMS和TOF应用实践

引言 2024年对我来说是技术成长与突破的一年。在这一年里&#xff0c;我不仅在技术领域拓展了深度和广度&#xff0c;还通过与客户合作的实际项目&#xff0c;成功实现了从单一MCU到MCU、MEMS与TOF技术融合的跨越。这一过程中&#xff0c;我深刻认识到&#xff0c;技术的进步不…

五、深入了解IoC

IoC控制反转&#xff0c;就是将对象的控制权交给Spring的IOC容器&#xff0c;由IOC容器创建及管理对象。也就是bean的存储。 5.1Bean的存储 共有两类注解类型可以实现&#xff1a; 1.类注解&#xff1a;Controller、Service、Repository、Component、Configuration. 2.方法注…

python-leetcode-有效的字母异位词

242. 有效的字母异位词 - 力扣&#xff08;LeetCode&#xff09; class Solution:def isAnagram(self, s: str, t: str) -> bool:return sorted(s) sorted(t)

RHCE实验详解

目录 实验分析 环境拓扑结构 项目需求 主机环境描述 实验步骤 一、密钥互信和主机名更改 二、DNS 三、NGINX 四、MARIADB 五、NFS 六、NTP 七、论坛服务 结果展示及痛点解答 实验分析 环境拓扑结构 项目需求 1. 172.25.250.101 主机上的 Web 服务要求提供 www.ex…

【Unity】ScrollViewContent适配问题(Contentsizefilter不刷新、ContentSizeFilter失效问题)

最近做了一个项目&#xff0c;菜单栏读取数据后自动生成&#xff0c;结果用到了双重布局 父物体 尝试了很多方式&#xff0c;也看过很多大佬的文章&#xff0c;后来自己琢磨了一下&#xff0c;当子物体组件自动生成之后&#xff0c;使用以下以下代码效果会好一些&#xff1a; …

linux如何修改密码,要在CentOS 7系统中修改密码

要在CentOS 7系统中修改密码&#xff0c;你可以按照以下步骤操作&#xff1a; 步骤 1: 登录到系统 在登录提示符 localhost login: 后输入你的用户名。输入密码并按回车键。 步骤 2: 修改密码 登录后&#xff0c;使用 passwd 命令来修改密码&#xff1a; passwd 系统会提…

Qt Creator 15.0.0如何更换主题和字体

1.打开Qt Creator 15.0.0 (Community)&#xff0c; 2.点击编辑栏3.点击Preferences... 4.修改主题&#xff0c;点击环境&#xff0c;修改Theme:栏 5.修改字体大小&#xff0c;点击文本编辑器&#xff0c;修改字号栏。&#xff0c;修改Theme:栏

Java 日志技术、Logback日志框架、日志级别

一. 日志 1. 日志&#xff1a;程序中的日志&#xff0c;通常就是一个文件&#xff0c;里面记录的是程序运行过程中的各种信息。 二. 日志技术 1. 日志技术&#xff1a;可以将系统执行的信息&#xff0c;方便的记录到指定的位置(控制台、文件中、数据库中) 2. 可以随时以开关的…

【多视图学习】显式视图-标签问题:多视图聚类的多方面互补性研究

Explicit View-labels Matter:A Multifacet Complementarity Study of Multi-view Clustering TPAMI 2024 论文链接 代码链接 0.论文摘要 摘要-一致性和互补性是促进多视图聚类&#xff08;MVC&#xff09;的两个关键因素。最近&#xff0c;随着流行的对比学习的引入&#…