You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么原生JS实现的useState中state为变量时不生效?如何用闭包解释React Hooks原理?

为什么第一个实现不生效,第二个实现生效

你对第二个实现生效原因的判断是完全正确的,核心就是闭包对作用域变量的持有特性,两个实现的差异本质是值拷贝和引用持有:

  • 第一个实现里,const state = _val 是基础类型的值拷贝:因为示例里的初始值是数字(基础类型),赋值操作会直接把_val当前的数值复制给state变量。后续你调用setState修改的是useState作用域里的_val,和已经被赋值完成的state没有任何关联,所以你拿到的count永远是第一次执行useState时拷贝的固定值1。
  • 第二个实现里,state被定义为返回_val的函数:函数是引用类型,你return [state, setState]时导出的是这个函数的引用,该函数定义在useState内部,天生形成闭包,永远持有对useState作用域内_val变量的访问权。你每次调用count()时,才会实时读取当前_val的最新值,所以调用setCount修改_val后,再调用count()就能拿到更新后的值。

用闭包解释React Hooks的运行原理

React Hooks的核心运行机制完全依赖闭包特性:

  1. React会在内部为每个函数组件维护一块独立的状态存储区(对应你示例里的_val,实际每个useState调用都会对应存储区里的一个固定槽位),这块存储区不会随着组件函数单次执行结束被销毁。
  2. 你调用useState时,拿到的状态值是React从对应存储槽位里读出来的当前最新值,返回的setXxx函数是闭包,持有对应槽位的引用,调用setXxx时就会修改这个槽位里的值,同时触发组件重新渲染。
  3. 每次组件重新渲染,本质就是重新执行一遍你的组件函数,执行过程中遇到的每个useState,都会从对应的存储槽位里拿最新的值返回给当前渲染周期的变量,这也是为什么你不需要像示例里那样写取值函数,React已经帮你在每次渲染时完成了取值操作。

额外补充:平时开发遇到的「Hooks闭包陷阱」也是这个特性导致的:某个渲染周期生成的事件回调、定时器函数如果持有了当前周期的状态变量,因为闭包特性,它拿到的永远是当前周期的固定值,不会跟着后续状态更新而变化。


内容的提问来源于stack exchange,提问作者GoonGamja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 17:18:02