iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >react中useEffect闭包的示例分析
  • 338
分享到

react中useEffect闭包的示例分析

2023-06-15 10:06:26 338人浏览 八月长安
摘要

这篇文章主要介绍React中useEffect闭包的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!问题代码看一段因为useEffect导致的闭包问题代码const btn = u

这篇文章主要介绍React中useEffect闭包的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

问题代码

看一段因为useEffect导致的闭包问题代码

const btn = useRef();const [v, setV] = useState('');useEffect(() => {    let clickHandle = () => {        console.log('v:', v);    }    btn.current.addEventListener('click', clickHandle)        return () => {        btn.removeEventListener('click', clickHandle)    }}, []);    const inputHandle = e => {    setV(e.target.value)}return (        <>            <input value={v} onChange={inputHandle} />            <button ref={btn} >测试</button>        </>    )

useEffect的依赖项数组为空,所以在页面渲染完成之后,内部代码只会执行一次,页面销毁再执行一次。此时在输入框中输入任意字符,再点击测试按钮,得到的输出为空,之后无论如何输入任何字符,再点击测试按钮时,输出的结果仍为空。

为什么会这样呢?其实就是闭包所造成的。

产生原因

函数的作用域在函数定义的时候就决定了

给btn注册点击事件时,作用域如下:

react中useEffect闭包的示例分析

能访问到的自由变量v此时还是空值。当点击事件触发时,执行点击回调函数,此时先创建执行上下文,会拷贝作用域链到执行上下文中。

  • 如果未在输入框内输入字符,此时点击拿到的v还是原来那个v

  • 如果在输入框内输入了字符,此时调用了setV修改了state,页面触发render,组件内部代码会重新执行一遍,重新声明了一个v,v就不再是原来那个v,这里点击事件里作用域中的v还是旧的v,这是两个不同的v

产生场景

  • 事件绑定。比如示例代码中,在页面最初渲染完成后只绑定一次事件的情况,比如使用echarts,在useEffect中获取echarts的实例并绑定事件

  • 定时器。页面加载后注册一个定时器,定时器内的函数也会产生如此的闭包问题。

解决办法

针对这个闭包问题下面大致给出5种解决办法

1. 以赋值方式直接修改v,并将修改v的方法用useCallback包裹起来

将修改v的方法用useCallback包裹起来,被useCallback包裹的函数将被缓存,由于依赖项的数组为空,所以这里直接赋值的方式修改的v是旧的v,此种方法不推荐,因为setState才是官方推荐的修改state的方式,这里仍然使用setV只是为了触发rerender

// v 的声明 由 const 改为 var,方便直接修改var [v, setV] = useState('');const inputHandle = useCallback(e => {    let { value } = e.target    v = value    setV(value)}, [])

2. 给useEffect的依赖项加上v

这也许是大多数人首先想到的办法,既然v是旧的,那么每次v更新的时候,重新注册一次事件不就行了,但是这样的会导致每次v更新都得重新注册,理论应该只需要注册一次的事件变成了多次。

3. 避免v被重新声明

以let或var的方式声明某个变量代替v,直接修改这个变量,而不是要setState相关函数触发render,这样就不会被重新声明,点击的回调函数里就能拿到“最新”的值,但这个方法更不推荐,就此示例来说,input组件由于没有rerender而至始至终都是显示空值,不符合操作预期。

4. 使用useRef代替useState

const btn = useRef();const vRef = useRef('');const [v, setV] = useStat('');useEffect(() => {    let clickHandle = () => {        console.log('v:', vRef.current);    }    btn.current.addEventListener('click', clickHandle)        return () => {        btn.removeEventListener('click', clickHandle)    }}, []);const inputHandle = e => {    let { value } = e.target    vRef.current = value    setV(value)}return (        <>            <input value={v} onChange={inputHandle} />            <button ref={btn} >测试</button>        </>    )

useRef的方案之所以有效,是因为每次input的change修改的是vRef这个对象的current属性,而vRef始终是那个vRef,即使rerender,由于vRef是对象,所以变量存储在栈内存中的值是该对象在堆内存中的地址,只是一个引用,只修改对象的某个属性,该引用并不会改变。所以点击事件中的作用域链始终访问的都是同一个vRef

react中useEffect闭包的示例分析

5. 将v换成对象类型

其实和使用useRef一样,只要是对象,仅修改某个属性也不会改变该state所指向的地址。

以上是“react中useEffect闭包的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网精选频道!

--结束END--

本文标题: react中useEffect闭包的示例分析

本文链接: https://www.lsjlt.com/news/279620.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • react中useEffect闭包的示例分析
    这篇文章主要介绍react中useEffect闭包的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!问题代码看一段因为useEffect导致的闭包问题代码const btn = u...
    99+
    2023-06-15
  • 浅谈react useEffect闭包的坑
    问题代码 看一段因为useEffect导致的闭包问题代码 const btn = useRef(); const [v, setV] = useState(''); use...
    99+
    2024-04-02
  • React useEffect不支持async function示例分析
    目录引言React为什么这么设计呢?简单改造1、简单改造的写法(不推荐)2、把异步提取成单独函数或自定义hook(推荐)引言 useEffect相比大家都耳熟能详啦,如下这种写法,应...
    99+
    2024-04-02
  • js中闭包的示例分析
    这篇文章主要介绍了js中闭包的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、说明闭包是具有很多变量和这些变量的环境的表现式(通常是函数),这些变量也是该表现式的一...
    99+
    2023-06-14
  • JavaScript闭包的示例分析
    小编给大家分享一下JavaScript闭包的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!闭包是JavaScript中的...
    99+
    2024-04-02
  • Javascript中return与闭包的示例分析
    这篇文章给大家分享的是有关Javascript中return与闭包的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、return的使用案例一:var a=1;...
    99+
    2024-04-02
  • React中ref的示例分析
    这篇文章给大家分享的是有关React中ref的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。为了摆脱繁琐的Dom操作, React提倡组件化, 组件内部用数据来驱动视图的...
    99+
    2024-04-02
  • JS中闭包与定时器的示例分析
    这篇文章主要介绍了JS中闭包与定时器的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。什么是闭包 有什么作用闭包就是能够读取其他函数内...
    99+
    2024-04-02
  • Go语言中基础闭包的示例分析
    这篇文章将为大家详细讲解有关Go语言中基础闭包的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一. 闭包概述闭包就是解决局部变量不能被外部访问的一种解决方案闭包是把函数当作返回值的一种应用二. 代...
    99+
    2023-06-25
  • 使用React/Hooks时需要注意过时闭包的示例分析
    小编给大家分享一下使用React/Hooks时需要注意过时闭包的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Hooks...
    99+
    2024-04-02
  • setTimeout与循环闭包的示例分析
    这期内容当中小编将会给大家带来有关setTimeout与循环闭包的示例分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。我在详细图解作用域链与闭包一文中的结尾留下了一个关...
    99+
    2024-04-02
  • React中的Virtual DOM示例分析
    本篇内容主要讲解“React中的Virtual DOM示例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“React中的Virtual DOM示例分析”吧!这是Choero...
    99+
    2023-06-29
  • javascript中变量提升和闭包的示例分析
    这篇文章主要介绍了javascript中变量提升和闭包的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。我们先来看一个题目:<s...
    99+
    2024-04-02
  • React中JSX与react事件的示例分析
    小编给大家分享一下React中JSX与react事件的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、JSX1.1、表...
    99+
    2024-04-02
  • react hooks的示例分析
    这篇文章将为大家详细讲解有关react hooks的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。React在16.8版本正式发布了Hooks。关注了很久,最近正...
    99+
    2024-04-02
  • webpack2+React的示例分析
    这篇文章主要为大家展示了“webpack2+React的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“webpack2+React的示例分析”这篇文章吧...
    99+
    2024-04-02
  • React中ref属性的示例分析
    这篇文章主要介绍了React中ref属性的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。概述首先,Refs 和 ref 是两个概念,Refs 是 React 提供的可...
    99+
    2023-06-15
  • React中setState源码的示例分析
    这篇文章将为大家详细讲解有关React中setState源码的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。React作为一门前端框架,虽然只是focus在MVV...
    99+
    2024-04-02
  • React中this绑定的示例分析
    这篇文章主要介绍了React中this绑定的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 我们在re...
    99+
    2024-04-02
  • JavaScript闭包原理及作用的示例分析
    小编给大家分享一下JavaScript闭包原理及作用的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!简介说明本文介绍JavaScript的闭包的作用、用途及其原理。闭包的定义闭包是指内部函数总是可以访问其所在的外部...
    99+
    2023-06-22
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作