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

为何未通过useState更新React状态,UI仍出现更新?

React状态对比与重渲染逻辑解析

核心原因:重渲染时会读取状态的当前值

你遇到的现象本质是重渲染触发时机和状态值读取逻辑的结合:

  1. 在代码示例1中,你通过strings[strings.length] = e.target.value直接修改了React状态数组的内容(可变操作),但并未调用setStrings更新状态引用。
  2. 但你调用了setInputValue,这个操作会触发组件重渲染。
  3. 组件重渲染时,App函数会重新执行,const [strings] = useState(...)会返回React内部管理的当前状态引用——也就是你之前修改过内容的那个数组。因此strings.map会遍历到新增元素,列表随之更新。

普通变量和React状态的本质区别

代码示例2中let strings: string[] = []是局部变量,和React状态的核心差异在于:

  • React状态由React内部存储维护,组件每次重渲染时,useState返回的是同一个状态引用(除非调用setX更新引用)。
  • 普通局部变量在组件每次重渲染时都会重新初始化(因为组件函数会从头执行一遍)。你在onChange中修改的数组,会在重渲染时被重置为空数组,自然看不到更新后的内容。

React的状态对比逻辑

你提到的Object.is对比,是React用来判断是否触发重渲染的逻辑:

  • 调用setState时,React会用Object.is对比新状态和旧状态的引用。如果引用不同(比如创建了新数组/对象),React会触发组件重渲染。
  • 如果引用相同(比如直接修改状态对象内容、未创建新引用),React不会因为这个状态的变化触发重渲染——但如果有其他状态更新触发了重渲染,组件依然会读取当前状态的最新内容。

重要提醒:不要直接修改React状态

虽然这次因其他状态更新触发重渲染看到了预期效果,但直接修改React状态是错误且危险的:

  • 会破坏React的状态快照机制,导致组件渲染结果与状态不一致,难以调试。
  • 依赖该状态的useEffect、useMemo等钩子可能不会触发预期更新(因为它们依赖状态引用,引用不变则不会重新执行)。
  • 正确的做法是使用不可变更新,比如:
    onChange={(e) => {
      setStrings([...strings, e.target.value]);
      setInputValue(e.target.value);
    }}
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 20:39:19