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,如果你是函数,那么他就会依次执行。

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

相关推荐
于慨21 小时前
Lambda 表达式、方法引用(Method Reference)语法
java·前端·servlet
石小石Orz21 小时前
油猴脚本实现生产环境加载本地qiankun子应用
前端·架构
从前慢丶21 小时前
前端交互规范(Web 端)
前端
CHU72903521 小时前
便捷约玩,沉浸推理:线上剧本杀APP功能版块设计详解
前端·小程序
GISer_Jing21 小时前
Page-agent MCP结构
前端·人工智能
王霸天21 小时前
💥别再抄网上的Scale缩放代码了!50行源码教你写一个永不翻车的大屏适配
前端·vue.js·数据可视化
小领航21 小时前
用 Three.js + Vue 3 打造炫酷的 3D 行政地图可视化组件
前端·github
@大迁世界21 小时前
2026年React大洗牌:React Hooks 将迎来重大升级
前端·javascript·react.js·前端框架·ecmascript
PieroPc21 小时前
一个功能强大的 Web 端标签设计和打印工具,支持服务器端直接打印到局域网打印机。Fastapi + html
前端·html·fastapi
悟空瞎说1 天前
深入 Vue3 响应式:为什么有的要加.value,有的不用?从设计到源码彻底讲透
前端·vue.js