React中的State为什么要叫做照片快照

  • 最近在自学React中,因为使用的公司内网,所以无法做笔记,那么就刚好在掘金上分享一下自己的心得,也当做笔记来使用。

  • 刚开始看React中的hooks的时候,用到了useState,但是看文档的时候迷迷糊糊的,为什么state叫做照片快照,这讲的到底是啥。

  • 首先这是官方的文档https://zh-hans.react.dev/learn/state-as-a-snapshot

  • 看完后我依然搞不清楚,但是通过询问AI和比较简便的例子,我还是搞懂了照片快照,也搞懂了React的渲染机制。

  • 首先官方给了个例子

javascript 复制代码
import { useState } from 'react';

export default function Counter() {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button onClick={() => {
        setNumber(number + 1)
        setNumber(number + 1)
        setNumber(number + 1)
      
      }}>+3</button>
    </>
  )
}
  • 这个例子很简单,就是当我们对按钮设置了一个点击事件,在点击的时候调用了3次setNumber(number+1),如果按照平常的逻辑来说,这时候h1标签应该返回结果是3,但是实际情况却是下图

h1标签却只显示了1,不卖关子直接说逻辑

其实照片快照就是你想象一个「点餐 - 做菜 - 上菜」的过程

  1. 顾客点餐(你调用 setState)

    你告诉服务员(React):"我要一份宫保鸡丁!"(setState({ dish: '宫保鸡丁' }))。

  2. 厨房做菜(React 计算新 UI)

    服务员把订单交给厨房(React 的渲染引擎),厨师需要时间切菜、炒菜(重新计算组件的 JSX)。

  3. 服务员上菜(UI 更新完成)

    只有菜做好了(渲染完成),服务员才会把菜端到你桌上(DOM 更新)。

关键点:

  • 你点完菜后,不能立刻吃到(state 不会马上更新)。
  • 服务员必须按流程完成做菜和上菜(React 必须完成渲染周期)。

生活化比喻

假设你在玩大富翁,要现金的方式:

直接给固定金额

  • 你说:"给我 100 元!"喊3次(setMoney(money + 100),setMoney(money + 100),setMoney(money + 100))
  • 银行每次都看你当前有 0 元,所以每次都只给 100 元。
scss 复制代码
setMoney(money + 100); // 等价于 setMoney(0 + 100)
setMoney(money + 100); // 还是 setMoney(0 + 100)
setMoney(money + 100); // 仍然是 setMoney(0 + 100)
  • 喊三次,最终只拿到 100 元。

  • 那么同理,我们的setNumber方法也只会

scss 复制代码
setNumber(number + 1); // 等价于 setNumber(0 + 1)
setNumber(number + 1); // 还是 setNumber(0 + 1)
setNumber(number + 1); // 仍然是 setNumber(0 + 1)
  • 所以h1的标签为1。

  • 那么有人就要说了,如果我要让他像我们平常那样执行3次,h1标签应该展示为3要怎么做呢?

ini 复制代码
 setNumber(number =>number + 1);
 setNumber(number =>number + 1);
 setNumber(number =>number + 1);

现在再来说原理

关键区别:传递「值」vs 传递「函数」

1. 传递普通值(如 number + 1)

  • React 行为 :直接使用当前渲染中的 number 值计算新值。

  • 你的例子:

    jsx

    scss 复制代码
    setNumber(number + 1); // 等价于 setNumber(0 + 1)
    setNumber(number + 1); // 还是 setNumber(0 + 1)
    setNumber(number + 1); // 仍然是 setNumber(0 + 1)
    • 结果 :三次都基于初始值 0 计算,最终只更新一次,number 变为 1。

2. 传递函数(如 prev => prev + 1)

  • React 行为:将所有更新函数按顺序排队,每个函数都基于上一次更新后的结果计算。

  • 你的例子:

    jsx

    ini 复制代码
    setNumber(number => number + 1); // 第一次:0 → 1
    setNumber(number => number + 1); // 第二次:1 → 2
    setNumber(number => number + 1); // 第三次:2 → 3
    • 结果 :三次更新依次生效,number 最终变为 3。

生活化比喻

还是你在玩大富翁,换了另外一种要现金的方式:

  • 你说:"把我现在的钱加 100 给我!"(setMoney(prev => prev + 100))
  • 银行第一次给 0+100=100 元,第二次给 100+100=200 元,第三次给 200+100=300 元。
  • 喊三次,最终拿到 300 元。

总结

写法 计算方式 最终结果
setNumber(number + 1) 基于当前渲染的 number 值(固定值) 只更新一次
setNumber(prev => prev + 1) 基于上一次更新后的结果(动态值) 累加多次

给一个我个人通俗易懂的解释:如果你不是函数的话,那么碰到修改的时候,他会把你要修改的记住,就是先不处理setNumber,而是等所有的方法执行完以后,再统一执行setNumber,如果你是函数,那么他就会依次执行。

我是罗密欧与猪过夜,感谢您的观看,有错误可以在底下评论区指正

相关推荐
用户461169657285 分钟前
网站 HTTPS 不稳定?证书排查指南
前端
n876517 分钟前
Playwright Java WEB UI 自动化实现框架与逻辑
java·前端·ui
keyipatience19 分钟前
TypeScript学习(1)
前端·javascript·学习·typescript·html·css3
xifangge20251 小时前
基于 JavaScript 实现 CNC 数控切削参数与螺纹公差纯前端核算引擎
开发语言·前端·javascript
wangruofeng1 小时前
2026 Web 技术选型指南,AI 时代如何选择适合项目的技术栈
前端·aigc·ai编程
honkun61 小时前
vue 表格组件 vxe-table 修改滚动条样式,修改滚动条样式,统一宽度、颜色与自动隐藏
前端·javascript·vue.js
爱勇宝2 小时前
研究数字孪生的这半年,做了个 Demo,也有了一些新想法
前端·程序员
不可能片场2 小时前
工程实践 一个缓存把选片从十分钟压到一分钟
前端·electron
前端小万2 小时前
探索副业五个月,最终以放弃告终
前端·后端·面试
FRing032 小时前
JavaScript入门到精通二十四(正则表达式、元字符、修饰符)
开发语言·前端·javascript·正则表达式