react 中 useCallback Hook 作用

一、性能优化

1. 防止函数的重复创建

1.1 函数组件重新渲染问题

在 React 函数组件中,每次组件重新渲染时,内部的函数都会被重新创建。

import React from "react";const ParentComponent = () => {// 每次ParentComponent重新渲染,handleClick函数都会重新创建const handleClick = () => {console.log("Button clicked");};return <ChildComponent onClick={handleClick} />;};const ChildComponent = React.memo(({ onClick }) => {return <button onClick={onClick}>Click me</button>;});

1.2 useCallback 的解决方案

`useCallback`可以用来解决这个问题。它会返回一个记忆化(memoized)的函数,只有在依赖项发生变化时,才会重新创建该函数。

import React, { useCallback } from "react";const ParentComponent = () => {// 只有在依赖项(这里没有依赖项,所以只会创建一次)改变时,handleClick才会重新创建const handleClick = useCallback(() => {console.log("Button clicked");}, []);return <ChildComponent onClick={handleClick} />;};const ChildComponent = React.memo(({ onClick }) => {return <button onClick={onClick}>Click me</button>;});

2. 优化组件渲染树

2.1 复杂组件结构中的性能影响

在大型应用中,组件树可能非常复杂,存在多层嵌套的组件关系。当父组件重新渲染时,如果不进行优化,可能会引发大量子组件的不必要渲染,导致性能下降。`useCallback`通过稳定函数引用,减少了子组件重新渲染的连锁反应。

2.2 示例场景

假设存在一个多层级的表单组件,其中包含多个输入字段和相关的验证函数。当表单中的某个输入字段变化导致父组件重新渲染时,如果不使用`useCallback`,所有依赖这些验证函数的子组件都可能重新渲染。使用`useCallback`来包裹这些验证函数后,只有当验证函数的依赖项(如验证规则)发生变化时,函数引用才会改变,从而稳定了子组件的渲染行为。

二、依赖管理与副作用控制

1. 精确的依赖管理

1.1 与 useEffect 结合时的作用

例如:当一个副作用函数依赖于一个外部函数时,如果不进行处理,每次组件重新渲染可能会导致副作用函数被重新执行,因为外部函数的引用在每次渲染时可能不同。

import React, { useEffect, useState } from "react";const ComponentWithEffect = () => {const [count, setCount] = useState(0);// 模拟一个外部函数,每次组件重新渲染都会重新创建const externalFunction = () => {return count * 2;};useEffect(() => {const result = externalFunction();console.log("Effect with result:", result);}, [externalFunction]);return (<div>Count: {count}{" "}<button onClick={() => setCount(count + 1)}>Increment</button></div>);};

在上述代码中,`externalFunction`的重新创建导致`useEffect`的依赖项不断变化,从而使副作用函数在每次组件重新渲染时都被执行。通过`useCallback`可以解决这个问题:

import React, { useEffect, useState, useCallback } from "react";const ComponentWithEffect = () => {const [count, setCount] = useState(0);// 使用useCallback来记忆化externalFunction,只有count变化时才会重新创建const externalFunction = useCallback(() => {return count * 2;}, [count]);useEffect(() => {const result = externalFunction();console.log("Effect with result:", result);}, [externalFunction]);return (<div>Count: {count}{" "}<button onClick={() => setCount(count + 1)}>Increment</button></div>);};

现在,`externalFunction`只有在`count`(依赖项)变化时才会重新创建,`useEffect`的副作用函数也只会在`externalFunction`真正改变时被执行,实现了更精确的依赖管理。

2. 副作用的触发控制

2.1 避免不必要的副作用执行

例如:在一个数据获取的场景中,如果获取数据的函数由于不必要的重新创建而频繁触发,可能会对服务器造成不必要的负载,并浪费用户的网络资源。

2.2 代码示例

import React, { useEffect, useState, useCallback } from "react";const DataFetchingComponent = () => {const [data, setData] = useState(null);// 数据获取函数,如果不进行优化,可能会频繁触发const fetchData = useCallback(() => {fetch("https://example.com/api/data").then((response) => response.json()).then((jsonData) => setData(jsonData));}, []);useEffect(() => {fetchData();}, [fetchData]);return (<div>{data ? <pre>{JSON.stringify(data)}</pre> : "Loading data..."}</div>);};

在这个例子中,`fetchData`函数使用`useCallback`进行优化,只有在`fetchData`的依赖项(这里没有依赖项,所以函数只会创建一次)变化时,才会重新创建该函数。这确保了数据获取操作(副作用)不会因为函数的不必要重新创建而频繁触发。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript:浏览器对象模型BOM

BOM介绍 浏览器对象模型&#xff08;Brower Object Model&#xff0c;BOM&#xff09;提供了独立于内容而与浏览器窗口进行交互的对象&#xff0c;其核心对象是window BOM由一系列相关的对象构成&#xff0c;并且每个对象都提供了很多方法和属性。 BOM与DOM区别 DOM是文档对…

SpringBoot 2.2.10 无法执行Test单元测试

很早之前的项目今天clone现在&#xff0c;想执行一个业务订单的检查&#xff0c;该检查的代码放在test单元测试中&#xff0c;启动也是好好的&#xff0c;当点击对应的方法执行Test的时候就报错 tip&#xff1a;已添加spring-boot-test-starter 所以本身就引入了junit5的库 No…

前后端、网关、协议方面补充

这里写目录标题 前后端接口文档简介前后端视角对于前端对于后端代码注册路由路由处理函数 关于httpGET/POST底层网络关于前端的获取 路由器网关路由器的IP简介公网IP(WAN IP)私网IP(LAN IP)无线网络IP(WIFI IP)查询路由器私网IP路由器公网IP LAN口与WIFI简介基本原理 手动配置电…

英伟达基于Mistral 7B开发新一代Embedding模型——NV-Embed-v2

我们介绍的 NV-Embed-v2 是一种通用嵌入模型&#xff0c;它在大规模文本嵌入基准&#xff08;MTEB 基准&#xff09;&#xff08;截至 2024 年 8 月 30 日&#xff09;的 56 项文本嵌入任务中以 72.31 的高分排名第一。此外&#xff0c;它还在检索子类别中排名第一&#xff08;…

【计算机网络】TCP网络特点2

断开连接 四次挥手 原因 TCP 四次挥手是为了满足 TCP 连接的全双工特性:两个方向都可以自由传输 保证数据传输的完整性&#xff1a;两方都完成了数据发送和接收并且都同意断开连接 可靠地终止连接以及避免数据混淆和错误等需求:每个方向都需要单独确认导致四次挥手过程 这些…

Opengl光照测试

代码 #include "Model.h" #include "shader_m.h" #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" //以上是放在同目录的头文件#include <glad/glad.h> #include <GLFW/glfw3.…

【MySQL】SQL语言

【MySQL】SQL语言 文章目录 【MySQL】SQL语言前言一、SQL的通用语法二、SQL的分类三、SQLDDLDMLDQLDCL 总结 前言 本篇文章将讲到SQL语言&#xff0c;包括SQL的通用语法,SQL的分类,以及SQL语言的DDL,DML,DQL,DCL。 一、SQL的通用语法 在学习具体的SQL语句之前&#xff0c;先来…

.netcore + postgis 保存地图围栏数据

一、数据库字段 字段类型选择(Type) 设置对象类型为&#xff1a;geometry 二、前端传递的Json格式转换 前端传递围栏的各个坐标点数据如下&#xff1a; {"AreaRange": [{"lat": 30.123456,"lng": 120.123456},{"lat": 30.123456…

T265相机双目鱼眼+imu联合标定(全记录)

最近工作用到t265&#xff0c;记录一遍标定过程 1.安装驱动 首先安装realsense驱动&#xff0c;因为笔者之前使用过d435i&#xff0c;装的librealsense版本为2.55.1&#xff0c;直接使用t265会出现找不到设备的问题&#xff0c;经查阅发现是因为realsense在2.53.1后就不再支持…

【C语言指南】C语言内存管理 深度解析

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《C语言指南》 期待您的关注 引言 C语言是一种强大而灵活的编程语言&#xff0c;为程序员提供了对内存的直接控制能力。这种对内存…

Python学习从0到1 day26 第三阶段 Spark ④ 数据输出

半山腰太挤了&#xff0c;你该去山顶看看 —— 24.11.10 一、输出为python对象 1.collect算子 功能: 将RDD各个分区内的数据&#xff0c;统一收集到Driver中&#xff0c;形成一个List对象 语法&#xff1a; rdd.collect() 返回值是一个list列表 示例&#xff1a; from …

【机器学习】机器学习中用到的高等数学知识-1.线性代数 (Linear Algebra)

向量(Vector)和矩阵(Matrix)&#xff1a;用于表示数据集&#xff08;Dataset&#xff09;和特征&#xff08;Feature&#xff09;。矩阵运算&#xff1a;加法、乘法和逆矩阵(Inverse Matrix)等&#xff0c;用于计算模型参数。特征值(Eigenvalues)和特征向量(Eigenvectors)&…

java项目-jenkins任务的创建和执行

参考内容: jenkins的安装部署以及全局配置 1.编译任务的general 2.源码管理 3.构建里编译打包然后copy复制jar包到运行服务器的路径 clean install -DskipTests -Pdev 中的-Pdev这个参数用于激活 Maven 项目中的特定构建配置&#xff08;Profile&#xff09; 在 pom.xml 文件…

【数据库取证】快速从服务器镜像文件中获取后台隐藏数据

文章关键词&#xff1a;电子数据取证、数据库取证、电子物证、云取证、手机取证、计算机取证、服务器取证 小编最近做了很多鉴定案件和参加相关电子数据取证比武赛&#xff0c;经常涉及到服务器数据库分析。现在分享一下技术方案&#xff0c;供各位在工作中和取证赛事中取得好成…

__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined

VUE_PROD_HYDRATION_MISMATCH_DETAILS 未明确定义。您正在运行 Vue 的 esm-bundler 构建&#xff0c;它期望这些编译时功能标志通过捆绑器配置全局注入&#xff0c;以便在生产捆绑包中获得更好的tree-shaking优化。 Vue.js应用程序正在使用ESM&#xff08;ECMAScript模块&#…

git撤销、回退某个commit的修改

文章目录 撤销某个特定的commit方法 1&#xff1a;使用 git revert方法 2&#xff1a;使用 git rebase -i方法 3&#xff1a;使用 git reset 撤销某个特定的commit 如果你要撤销某个很早之前的 commit&#xff0c;比如 7461f745cfd58496554bd672d52efa8b1ccf0b42&#xff0c;可…

Flume和kafka的整合

1、Kafka作为Source 【数据进入到kafka中&#xff0c;抽取出来】 在flume的conf文件夹下&#xff0c;有一个flumeconf 文件夹&#xff1a;这个文件夹是自己创建的 创建一个flume脚本文件&#xff1a; kafka-memory-logger.conf Flume 1.9用户手册中文版 — 可能是目前翻译最完…

JavaSE常用API-日期(计算两个日期时间差-高考倒计时)

计算两个日期时间差&#xff08;高考倒计时&#xff09; JDK8之前日期、时间 Date SimpleDateFormat Calender JDK8开始日期、时间 LocalDate/LocalTime/LocalDateTime ZoneId/ZoneDateTIme Instant-时间毫秒值 DateTimeFormatter Duration/Period

支持向量机SVM——基于分类问题的监督学习算法

支持向量机&#xff08;SVM&#xff0c;Support Vector Machine&#xff09;是一种常用于分类问题的监督学习算法&#xff0c;其核心思想是通过寻找一个最佳的超平面来将不同类别的数据点分开&#xff0c;从而实现分类。支持向量机广泛应用于模式识别、文本分类、图像识别等任务…

node对接ChatGpt的流式输出的配置

node对接ChatGpt的流式输出的配置 首先看一下效果 将数据用流的方式返回给客户端,这种技术需求在传统的管理项目中不多见,但是在媒体或者有实时消息等功能上就会用到,这个知识点对于前端还是很重要的。 即时你不写服务端,但是服务端如果给你这样的接口,你也得知道怎么去使用联…