React state 更新时机

设置 state 只会为下一次渲染变更 state 的值
一个 state 变量的值永远不会在一次渲染的内部发生变化
React 会使 state 的值始终"固定"在一次渲染的各个事件处理函数内部
React 会等到事件处理函数中的所有代码都运行完毕再处理 state 更新

  1. 在一个函数中,多次设置state, 最终结果由最后一次决定
js 复制代码
export default function Counter() {
 const [number, setNumber] = useState(0);
 return (
   <>
     <h1>{number}</h1>
     <button onClick={() => {
     // 第一次执行时,number为0
       setNumber(number + 1); // 相当于setNumber(0 + 1),React 准备在下一次渲染时将 number 更改为 1,React 将 "替换为 1" 添加到其队列中。
       setNumber(number + 1); // 相当于setNumber(0 + 1),React 准备在下一次渲染时将 number 更改为 1,React 将 "替换为 1" 添加到其队列中。
       setNumber(number + 1); // 相当于setNumber(0 + 1),React 准备在下一次渲染时将 number 更改为 1,React 将 "替换为 1" 添加到其队列中。
       // 执行结果 number = 1
     }}>+3</button>
   </>
 )
}
  1. 即使事件处理函数的代码是异步的,它获取到的state也是与本次最初执行时的值保持一致的,state在一次执行时不会改变。
js 复制代码
export default function Counter() {
  const [number, setNumber] = useState(0);
  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 5);
        setTimeout(() => {
          alert(number); // 0 在onClick执行时,number的值就被固定了。state 在"获取 UI 的快照"时就被"固定"了
        }, 3000);
      }}>+5</button>
    </>
  )
}

如何在重新渲染前,多次更新同一个state

setNumber(n => n + 1)

通过传入一个更新函数 n=>n+1来更新state的值

js 复制代码
export default function Counter() {
  const [number, setNumber] = useState(0);
  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(n => n + 1); // n => n + 1 是一个函数。React 将它加入队列。
        setNumber(n => n + 1); // n => n + 1 是一个函数。React 将它加入队列。
        setNumber(n => n + 1); // n => n + 1 是一个函数。React 将它加入队列。
      }}>+3</button>
    </>
  )
}

当在下次渲染期间调用 useState 时,React 会遍历队列。 之前的 state 的值是 0,所以这就是 React 作为参数 n 传递给第一个更新函数的值。然后 React 会获取上一个更新函数的返回值,并将其作为 n 传递给下一个更新函数,以此类推:

更新队列 n 返回值
n => n + 1 0 0 + 1 = 1
n => n + 1 1 1 + 1 = 2
n => n + 1 2 2 + 1 = 3

React 会保存 3 为最终结果并从 useState 中返回。

相关推荐
油丶酸萝卜别吃5 小时前
utils.js 说明文档
开发语言·javascript·ecmascript
zyplayer-doc8 小时前
VuePress类静态文档站和动态知识库怎么选:两种技术路线的适用场景
javascript·人工智能·后端·安全·智能手机
用户938515635079 小时前
从零在浏览器里跑 DeepSeek-R1:WebGPU + Transformers.js 全链路实战(三)
前端·react.js·typescript
To_OC11 小时前
写了 5 个表单 Demo 后,我终于彻底搞懂了 React 受控与非受控组件
前端·react.js·前端框架
码哥DFS12 小时前
构造函数、实例对象、对象原型 ----三者关系
开发语言·javascript·原型模式
满栀58512 小时前
vue动态路由效果
前端·javascript·vue.js·前端框架·vue
jjw_zyfx14 小时前
css vue vite实现闪烁的呼吸效果
javascript·css·vue.js
sunly_14 小时前
React useActionState 的用法详解
前端·javascript·react.js
cyadyx15 小时前
【Three.js】Three.js 中加载 3D 模型
前端·javascript·3d
汉堡大王952715 小时前
前端工程师 TypeScript 上手指南:一条清晰的从入门到精通路线
前端·javascript·react.js