首页 > 其他分享 >React中函数组件中闭包陷阱如何产生,如何解决?

React中函数组件中闭包陷阱如何产生,如何解决?

时间:2024-07-23 15:28:21浏览次数:13  
标签:闭包 count 中闭 useCallback React 如何 useState 陷阱 useEffect

在什么情况下会产生闭包陷阱?

在React中,当使用useState和useEffect以及useCallback时,我们必须得注意闭包陷阱,避免出现一些意外的行为

什么是闭包陷阱?

闭包是指一个函数可以访问其词法作用域之外的变量。

闭包主要发生的集中情况?

在 useState 中的闭包陷阱

在 useEffect 中的闭包陷阱

在 useCallback 中的闭包陷阱

useState陷阱

出现的问题是:

        当我们想做一个点击事件数值+1时,点击按钮,发现数值更新了,打印的值还是上次的,没有更新;是因为useState修改状态,是异步执行无法直接获取更新后的值

export default function Hooks() {
	const [count, setCount] = useState(0);
	const add = () => {
		setCount( count + 1 );
		console.log(count, '修改前的值');
		}
		return (
			<div>
				<span>{count}</span>
				<button onClick={ add }> 数值加1 </button>
			</div>
			);
		}

解决方法是:

        通过promise.then链式调用;

        可以通过useRef获取最新值

useEffect陷阱

出现的问题是:

        闭包过期

import React, { useState, useEffect } from 'react'
export default function Hooks3() {
	const [count, setCount] = useState(0);
		useEffect(() => {
			setInterval(() => {
			   setCount(count + 1)
			}, 1000)
		}, [])
	useEffect(()=>{
		setInterval(() => {
			console.log(`Count: ${count}`)
		}, 1000);
	}, []);
	return (
		<div>
			<span>{count}</span>
		</div>
		);
	}

这个代码执行完页面上会一直显示count=1

useEffect的第二个参数为空数组时,只会执行一次,会一直执行

闭包陷阱产生的原因是useEffect的函数里引用了某个state,形成了闭包。

解决方法:

        给useEffect的第二个参数添加一个依赖项;

        每次更新时,添加计时器,清除定时器

useCallback陷阱

出现的问题是:

        useCallback 本来拿来优化性能,当依赖变化不用重新注册该函数

        使用时也会出现一定的问题

        陷阱:获取父组件的值,不是最新的值,说明useCallback依赖为空数组

解决方法:

        给useCallback第二个参数添加依赖的数据,依赖变化了函数会重新生成

        

标签:闭包,count,中闭,useCallback,React,如何,useState,陷阱,useEffect
From: https://blog.csdn.net/iL_05_03/article/details/140629618

相关文章

  • Python中的global关键字是如何工作的?
    在Python中,global关键字扮演着特殊而重要的角色,它主要用于在函数内部声明全局变量。理解global关键字的工作原理,首先需要明确Python中变量作用域的概念,以及为什么需要global关键字。下面,我将详细解释global关键字的工作机制,包括其作用、使用场景、注意事项,以及它在Python编......
  • 如何在clouser中设置参数
    我有一个获取参数的函数callId我在此处检查并在第一个日志中得到结果“用ID初始化日历:1”但是对于第二个日志,我无法获取ID“选择日历ID:”如何在clouser选择中发送ID?functionupdateCalendar(events,callId){console.log('Initializingcalendar......
  • 如何在 pyplot 中的条形右侧添加标志/图像
    这是我的代码importmatplotlib.pyplotaspltfig=plt.Figure()ax=fig.axes[0]ax.barh(bar_y_corodinates_list,bar_lengths_list,tick_label=countries_list)这是我想添加标志的地方,即小图像就像我传递Y轴标签的国家/地区列表一样我想传递光盘中标......
  • 我们如何从 pickle 文件中获取注释,这些注释将告诉我们 pickle 文件中存储的对象数量和
    有人在Pickle文件中存储了多个对象。现在我想取消该文件,但我如何知道Pickle文件中存储了多少对象?是否有任何注释或其他内容可供我们获取有关Pickle文件的信息?你不能直接从pickle文件本身获取注释来说明存储了多少个对象或这些对象的类型。Pickle文件不存储此类元数......
  • 使用循环引用为注释类型创建别名时如何避免名称错误?
    正如这个伟大的答案所建议的那样,从Python3.7开始,如果使用from__future__importannotations指令,则可以在类型注释中使用前向声明。但是,如果我想创建,这仍然不起作用注释类型的别名:from__future__importannotationsimporttypingMyType1=typing.Un......
  • Python中如何实现字符串的查询和替换?
    在Python中,字符串的查询和替换是编程中常见的任务,它们可以通过Python的内置方法和库来高效实现。这些操作对于文本处理、数据清洗、日志分析等场景尤为重要。下面,我将详细阐述如何在Python中实现字符串的查询和替换,包括基础方法、高级技巧以及在实际应用中的注意事项。字符......
  • 如何注释保存类对象的变量的类型
    我正在使用一个变量来保存不同类的工厂。代码运行,但PyCharmIDE希望我注释工厂变量的类型,因为我正在调用它。Q1:我应该如何注释“工厂”变量,为XXX插入的类型是什么?Q2:这是对工厂进行编码的Python方式吗?classFoo(object):passclassBar:passfactor......
  • 美团面试:如何计算一个对象在内存中占多少个字节?
    在分配对象的时候会有一些基本的规则,我们可以根据一些规则大致能判断出来对象大小。在HotspotVM中,对象在内存中的存储布局分为三个区域:对象头(Header)实例数据(InstanceData)对齐填充(Padding)对象头(Header)对象头包括以下三部分:MarkWord:用于存储对象运行时的数据,例如Has......
  • 实例说明如何使用Java 8的Function接口使得代码更加简洁以及降低重复性
    什么是Function接口?Function接口是Java8中引入的一个功能性接口,位于java.util.function包下。它代表了一个接受一个参数并产生结果的函数。这个接口只有一个抽象方法apply(Tt),用于对传入的参数应用某种操作并返回一个结果。@FunctionalInterfacepublicinterfaceFunct......
  • 如何使用OpenCV轨迹栏控制圆半径?
    我正在尝试添加一个opencv轨迹栏来调整我用于二进制掩模图像的圆半径值。问题是bitwise_and或bitwise_ortwe参数结果是相同的。掩模图像解释一下。|||这是我的代码:Here'smycode:---python#importopencvandnumpyimportcv2importnumpyasnp#Bla......