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

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

相关推荐
LaoZhangAI1 小时前
Kiro vs Cursor:2025年AI编程IDE深度对比
前端·后端
止观止1 小时前
CSS3 粘性定位解析:position sticky
前端·css·css3
爱编程的喵1 小时前
深入理解JavaScript单例模式:从Storage封装到Modal弹窗的实战应用
前端·javascript
lemon_sjdk1 小时前
Java飞机大战小游戏(升级版)
java·前端·python
G等你下课1 小时前
如何用 useReducer + useContext 构建全局状态管理
前端·react.js
欧阳天羲1 小时前
AI 增强大前端数据加密与隐私保护:技术实现与合规遵
前端·人工智能·状态模式
慧一居士1 小时前
Axios 和Express 区别对比
前端
I'mxx2 小时前
【html常见页面布局】
前端·css·html
万少2 小时前
云测试提前定位和解决问题 萤火故事屋 上架流程
前端·harmonyos·客户端