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

使用useCallback引发对闭包的理解

一、先简单介绍一下闭包:

闭包是 JavaScript 中的重要概念,它指的是一个函数可以“记住”并访问其词法作用域,即使在这个函数的外部被执行。简单来说,闭包是由函数及其相关的环境组合而成的。

闭包的特性

函数内部可以访问外部变量:

  • 闭包允许一个函数访问其外部作用域中的变量,即使这个函数在外部被调用。

保持状态:

  • 闭包可以用来保持状态,因为它可以“记住”外部变量的值。

私有变量:

  • 通过闭包,可以创建私有变量,这些变量不能被外部代码直接访问,只能通过闭包内部的函数进行访问和修改。

简单示例:

匿名函数持久化存储了外部count的值(保持状态)

function createCounter() {let count = 0; // count 是一个私有变量return function() {count += 1; // 访问外部变量 countreturn count; // 返回当前的 count 值};
}const counter = createCounter();console.log(counter()); // 输出 1
console.log(counter()); // 输出 2
console.log(counter()); // 输出 3

二、在React中使用useState产生闭包:

import React, { useState } from 'react';const Counter = () => {const [count, setCount] = useState(0);const increment = () => {setCount(count + 1); // 这里使用了捕获的 count 值setCount(count + 1); // 这次仍然使用的是同样的捕获值};return (<div><p>Count: {count}</p><button onClick={increment}>Increment</button></div>);
};export default Counter;

当你点击按钮时,increment 函数会调用 setCount 两次,但由于 count 是在函数创建时捕获的值,这导致 count 只增加 1,而不是 2。(内部访问外部变量,由于内部两次访问的count的值是一样的,所以无论调用多少次,这只导致count只能增加一次)

 解决方法:函数式的更新

所以为了避免这个问题,React采用函数形式的更新方式,以此来访问最新的状态值:

import React, { useState } from 'react';const Counter = () => {const [count, setCount] = useState(0);const increment = () => {setCount(count + 1); // 这里使用了捕获的 count 值setCount(count + 1); // 这次仍然使用的是同样的捕获值};return (<div><p>Count: {count}</p><button onClick={increment}>Increment</button></div>);
};export default Counter;

三、 useCallback的依赖项:

创建一个外部的useState:

const [todoList, setTodoList] = useState([]);

为什么要添加todolist的依赖项?

使用了依赖项:

const openCheckModal = useCallback((id) => {setCurrentData(() => todoList.filter(item => item.id === id));setShowCheckModal(true);
}, [todoList]);

 查看定义:

useCallback缓存函数:

它确保只有在依赖项变化时才重新创建函数,从而避免子组件不必要的重新渲染。

解释:

由于闭包的问题,内部使用了外部变量(todolist),当外部变量更新的时候需要更新到最新的状态,换句话说,在初始化的时候 const openCheckModal 这个变量只加载了一次,由于闭包的问题,todolist存储的一直是初始化的todolist,当todolist改变的时候,此时也应该去动态更新当前这个const 变量

这样不会导致闭包的出现,也可以使得内部引用到的是外部最新的数据

在下面的例子中也使用了todolist,为什么只有第一个要添加todolist的依赖项呢?

 不使用依赖项

const addItem = useCallback((value) => {const dataItem = {id: new Date().getTime(),content: value,completed: false};setTodoList((todoList) => [...todoList, dataItem]);setInputShow(false);
}, []);

由于todolist形参传递,引用来自useState定义的变量,无关与addItem这个变量,也不会产生闭包,所以不需要传递todolist依赖项

总结:

当你将外部变量放入依赖数组中时,有几个要点需要理解:

  • 保持一致性: 如果在回调函数内部使用了某个外部变量(例如 props 或 state),将这个变量放入依赖数组中可以确保你使用的是最新的值。这避免了闭包问题,即在回调函数中引用的变量是旧值。
  • 不必要的重新调用: 如果依赖数组中的变量发生变化,但回调函数并没有被调用(例如,函数没有被某个事件触发),那么不会造成逻辑错误。只有在实际调用这个回调函数时,内部逻辑会基于最新的依赖值执行。

要想使用最新的值,就需要动态更新当前useCallback,添加外部变量的依赖项,以便获取最新的数据

相关文章:

使用useCallback引发对闭包的理解

一、先简单介绍一下闭包: 闭包是 JavaScript 中的重要概念&#xff0c;它指的是一个函数可以“记住”并访问其词法作用域&#xff0c;即使在这个函数的外部被执行。简单来说&#xff0c;闭包是由函数及其相关的环境组合而成的。 闭包的特性 函数内部可以访问外部变量: 闭包…...

gvim添加至右键、永久修改配置、放大缩小快捷键、ctrl + c ctrl +v 直接复制粘贴、右键和还原以前版本(V)冲突

一、将 vim 添加至右键 进入安装目录找到 vim91\install.exe 管理员权限执行 Install will do for you:1 Install .bat files to use Vim at the command line:2 Overwrite C:\Windows\vim.bat3 Overwrite C:\Windows\gvim.bat4 Overwrite C:\Windows\evim.bat…...

腾讯云-COS

COS 对象存储 是一种可扩展的云端数据存储服务。它适用于存储任意类型的文件&#xff0c;并且可以针对这些文件进行访问控制。 CORS 跨域资源共享 是一种机制&#xff0c;它使用额外的HTTP头来告诉浏览器允许一个域上的Web应用请求另一个域上的资源。当需要从一个域名下的网页向…...

蓝桥杯每日真题 - 第16天

题目&#xff1a;&#xff08;卡牌&#xff09; 题目描述&#xff08;13届 C&C B组C题&#xff09; 解题思路&#xff1a; 题目分析&#xff1a; 有 n 种卡牌&#xff0c;每种卡牌的现有数量为 a[i]&#xff0c;所需的最大数量为 b[i]&#xff0c;还有 m 张空白卡牌。 每…...

基因组之全局互作热图可视化

引言 PlotHiC 是一个专为 Hi-C 数据可视化分析而设计的 Python 包。Hi-C 技术是一种能够检测染色体三维结构的实验方法&#xff0c;它能揭示 DNA 在细胞核内的三维组织结构。为了更好地展示和解释这些复杂的数据&#xff0c;PlotHiC[1] 可以帮助用户方便地绘制Hi-C 数据的热图。…...

基于Lora通讯加STM32空气质量检测WIFI通讯

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着环境污染问题的日益严重&#xff0c;空气质量的监测与管理已经…...

STM32 极速入门第一天基础拓展 驱动i2c屏幕 ( 使用PlatformIO开发STM32单片机 )

输入输出模式解析 输出模式 在输出模式下&#xff0c;通常不需要设置上下拉电阻. 输出电平由 LL_GPIO_SetOutputPin 和 LL_GPIO_ResetOutputPin 函数直 接控制。 输入模式 在输入模式下&#xff0c;设置上下拉电阻是非常重要的. 输入引脚悬空时可能会导致不确定的电平&#xf…...

【WPF】Prism学习(五)

Prism Commands 1.错误处理&#xff08;Error Handling&#xff09; Prism 9 为所有的命令&#xff08;包含AsyncDelegateCommand&#xff09;提供了更好的错误处理。 避免用try/catch包装每一个方法根据不同遇到的异常类型来提供特定的逻辑处理可以在多个命令之间共享错误处…...

RabbitMQ的基本概念和入门

RabbitMQ 的基本概念和入门 RabbitMQ 是一款流行的开源消息队列中间件&#xff0c;实现了高级消息队列协议&#xff08;AMQP&#xff09;。它使用Erlang语言编写&#xff0c;具备高可用性、可扩展性和易用性等特点&#xff0c;广泛应用于各种分布式系统中。本文将详细介绍Rabb…...

Shell脚本6 -- 条件判断if

声明&#xff1a; 本文的学习内容来源于B站up主“泷羽sec”视频【shell编程&#xff08;4&#xff09;脚本与用户交互以及if条件判断】的公开分享&#xff0c;所有内容仅限于网络安全技术的交流学习&#xff0c;不涉及任何侵犯版权或其他侵权意图。如有任何侵权问题&#xff0c…...

经验笔记:从生成 SSH 密钥到成功连接测试(以Gitee为例)

从生成 SSH 密钥到成功连接测试的经验笔记&#xff08;以Gitee为例&#xff09; 1. 生成 SSH 密钥对 选择合适的加密算法 ED25519&#xff1a; 密钥长度&#xff1a;私钥 256 位&#xff08;32 字节&#xff09;&#xff0c;公钥 256 位&#xff08;32 字节&#xff09;&#…...

Object.defineProperty和响应式

Object.defineProperty()是一个监听对象属性变化的方法。一般情况下我们是不会直接使用的&#xff0c;或者说我们遇到的场景还没有这么高级。 最有名的例子就是Vue2的响应式实现&#xff0c;就是通过这个方法来实现的。 用起来不难&#xff0c;就是个API&#xff0c;只是用的…...

前端web

题目&#xff1a;制作带有下拉悬停菜单的导航栏 效果图 一、先制作菜单栏 <body> <div id"menu"> <div id"container"> <div class"item">游戏1 <div cla…...

DDNet 服务器配置教程 Linux 环境

DDNet 服务器配置教程 Linux 环境 配置之前可以参考一下官方网址给出的内容 官方网址&#xff1a;DDNet官方 环境说明 OS: Debian 11 安装 可以直接从官网下载&#xff0c;也可以使用这个链接: Linux_DDNet 下载链接 上文中给的链接会因为更新而出现版本落后的情况&#x…...

Vue 2 —监视器实现动态切换表单属性值

目录 一、需求背景 二、监视器语法 三、实例展示 1、HTML部分 2、JS部分 四、使用场景总结 1. 表单验证 2. 动态更新 UI 3. 数据同步 4. 计算属性的替代方案 计算属性的优势 : 简洁性&#xff1a; 监视器的优势 : 灵活性&#xff1a; 多属性依赖&#xff1a; 副…...

Qt_day10_程序打包(完结)

目录 1. 设置图标 2. Debug和Release版本 3. 动态链接库 4. 打包 5. 联系项目要求 Qt开发的程序最终都是要给用户使用的&#xff0c;用户的电脑上不可能装一个Qt的开发环境导入项目使用。因此项目项目开发完成后需要打包——制作成安装包&#xff0c;用户直接下载并安装即可使用…...

golang通用后台管理系统09(系统操作日志记录)

1.日志工具类 package log/**** 日志记录 wangwei 2024-11-18 15:30*/ import ("log""os""path/filepath""time" )// 获取以当前日期命名的日志文件路径 func getLogFilePath() string {currentDate : time.Now().Format("2006-…...

如何确保爬取的数据准确性和完整性?

在数据驱动的业务环境中&#xff0c;爬虫程序的准确性和完整性至关重要。本文将探讨如何使用Java编写爬虫程序&#xff0c;并确保其在爬取数据时的准确性和完整性。 1. 精确的HTML解析 确保数据准确性的第一步是精确地解析HTML。Jsoup是Java中常用的HTML解析库&#xff0c;它提…...

【java】JDK安装

Java Downloads | Oracle 中国 next 注意安装的路径 环境变量...

科技改变工作方式:群晖NAS安装内网穿透实现个性化办公office文档分享(1)

文章目录 前言1. 本地环境配置2. 制作本地分享链接3. 制作公网访问链接4. 公网ip地址访问您的分享相册5. 制作固定公网访问链接 前言 本文将详细介绍如何在群晖NAS上安装Synology Office和Synology Drive Server&#xff0c;并利用Cpolar内网穿透工具为本地文档配置固定的公网…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

uniapp 实现腾讯云IM群文件上传下载功能

UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中&#xff0c;群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS&#xff0c;在uniapp中实现&#xff1a; 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...

comfyui 工作流中 图生视频 如何增加视频的长度到5秒

comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗&#xff1f; 在ComfyUI中实现图生视频并延长到5秒&#xff0c;需要结合多个扩展和技巧。以下是完整解决方案&#xff1a; 核心工作流配置&#xff08;24fps下5秒120帧&#xff09; #mermaid-svg-yP…...