一个关于 useState 的误解

本文写于 2020 年 11 月 17 日

前两天有人问了我一个问题,他有一段这样的代码:

function App() {
const [n, setN] = useState(0);
return (
<div>
<h1>{n}</h1>
<button onClick={() => setN((x) => x + 1)}>+1</button>
<button onClick={() => setTimeout(() => console.log(n), 3000)}>
log
</button>
</div>
);
}

如果他先点击 “+1” 按钮,再点击 log 按钮,控制台就会在 3s 后输出 h1 内显示的值——即 +1 后的数字。

但是如果他先 log,再点击 “+1”,获得的却还是上一次的数值,并不是 h1 显示的值。

这是为什么?

因为 setState 不是改变了 state 的值,而是有了一个新的 state。

React 重新执行了组件函数,将原来的值进行处理之后赋给了新的值——所以原来的值永远是原来的值

换个角度说,假设你有一个函数如下:

function foo() {
const a = 1;
}

如果 foo 执行了两次,那么这两次创建的 a 会是一个 a 吗?当然不是呀。

此时在该函数里放一个闭包:

function foo() {
const a = 1; setTimeout(() => consol.log(a), 1000);
}

第二次执行的 setTimeout 可能访问到第一次执行时创建的 a 变量吗?

因此,setTimeout 是在旧的函数里触发的,3s 后读取的就是旧的函数里的 n 值。

(完)

一个关于 useState 的误解的更多相关文章

  1. 一个 Object.assign 的误解

    mozilla中对 Object.assign 的解释如下地址: mozilla 其中有说到 注意, Object.assign 会跳过那些值为 null 或 undefined 的源对象. 一直以为 ...

  2. 关于NSOperationQueue,一个容易让初学者误解的问题

    凡是学习NSOperationQueue的人,都会遇到setMaxConcurrentOperationCount这个函数.在网上的许多博文中,都将setMaxConcurrentOperationC ...

  3. 一文澄清网上对 ConcurrentHashMap 的一个流传甚广的误解!

    大家好,我是坤哥 上周我在极客时间某个课程看到某个讲师在讨论 ConcurrentHashMap(以下简称 CHM)是强一致性还是弱一致性时,提到这么一段话 这个解释网上也是流传甚广,那么到底对不对呢 ...

  4. !!误解--var vm = new vue({}) 与 export default {} 是一回事儿??

    这两者完全不是同一回事.export default {} 是es6的module中的语法, 而var vm = new vue({}) 是创建一个vue实例.引起误解是因为用了webpack开发vu ...

  5. 手写useState与useEffect

    手写useState与useEffect useState与useEffect是驱动React hooks运行的基础,useState用于管理状态,useEffect用以处理副作用,通过手写简单的us ...

  6. 运用webkit绘制渲染页面原理解决iscroll4闪动的问题

    原:http://www.iunbug.com/archives/2012/09/19/411.html 已经有不少前端同行抱怨iScroll4的各种问题,我个人并不赞同将这些问题归咎于iScroll ...

  7. RESTful API URI 设计: 查询(Query)和标识(Identify)

    相关文章:RESTful API URI 设计的一些总结. 问题场景:删除一个资源(Resources),URI 该如何设计? 应用示例:删除名称为 iPhone 6 的产品. 是不是感觉很简单呢?根 ...

  8. javascript 杂记

    博客 http://www.cnblogs.com/onepixel/ http://www.cnblogs.com/ahthw/p/4240220.html#javascript call.appl ...

  9. ThinkPHP的URL重写+路由+伪静态,实现SEO效果。

    1.URL重写,隐藏网址中的Index.php. ThinkPHP 作为 PHP 框架,是单一入口的,那么其原始的 URL 便不是那么友好.但 ThinkPHP提供了各种机制来定制需要的 URL 格式 ...

随机推荐

  1. SQL语句之Column 'Status' in where clause is ambiguous错误

    问题: AND created_by IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) limit 0, 10]; Column 'created_by' in where cla ...

  2. python中类变量和实例变量的区别

    类变量:可在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的).实例变量:实例化之后,每个实例单独拥有的变量. class student(): age = 0 name = 'stu ...

  3. python中一切皆对象的理解

    一切皆对象? 学过Java都知道,Java中有8个基本类型,其余的都是继承自Object类的引用类型.方法内的基本类型变量会在栈上分配,而引用类型会通过逃逸分析来决定在栈上分配或堆上分配.Java中关 ...

  4. Numpy常用random随机函数汇总

    Numpy常用random下的随机函数汇总 官方文档地址:https://docs.scipy.org/doc/numpy-1.14.0/reference/routines.random.html ...

  5. STM32 HAL库与标准库的区别_浅谈句柄、MSP函数、Callback函数

    最近笔者开始学习STM32的HAL库,由于以前一直用标准库进行开发,于是发现了HAL库几点好玩的地方,在此分享. 1.句柄在STM32的标准库中,假设我们要初始化一个外设(这里以USART为例)我们首 ...

  6. 我的python学习记04

    列表,元组,字典的使用一.列表列表的格式:list[元素1,元素2,--]列表也是一个有序集合,下标索引从0开始与字符串类似1.在列表中添加数据append:list.append(添加元素) (在最 ...

  7. java中设置准确的时间日期类的用法

    5.日期Date相关类: 题目1: 设置准确的时间(jdk1.1以后Date的setHours不被推荐了,所以要用Calendar设置时间) import java.util.*;public cla ...

  8. Linux安装Redis步骤和make遇到的坑

    Linux安装Redis服务步骤 1.获取redis资源 ​​​​​​​cd /usr/local wget https://mirrors.huaweicloud.com/redis/redis-6 ...

  9. linux ping的三个数字(56,84,64)

    参考:ping 深入剖析:https://www.cnblogs.com/aozhejin/p/15917312.html windows默认是32字节,linux是56字节说的都是数据包大小注意:1 ...

  10. ASP.NET Core WebApi返回结果统一包装实践

    前言 近期在重新搭建一套基于ASP.NET Core WebAPI的框架,这其中确实带来了不少的收获,毕竟当你想搭建一套框架的时候,你总会不自觉的去想,如何让这套框架变得更完善一点更好用一点.其中在关 ...