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

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

相关推荐
奇奇怪怪的4 小时前
从开发到生产——生成优化、监控、安全与成本
前端
10share4 小时前
100行代码 模拟实现Vue 响应式系统
前端·vue.js
Heo4 小时前
Vite进阶用法详解
前端·javascript·面试
狂炫冰美式5 小时前
人均配了AI, 为什么公司还是没变快? 🤔 本质还是分布式系统问题
前端·后端·架构
乘风gg6 小时前
多 Agent 不是万能的!搞懂这 5 个原则,少走 1 年弯路!
前端·agent·ai编程
猩猩程序员6 小时前
Vercel 推出 Agent 框架 Eve:让 AI Agent 像写 Web 应用一样简单
前端
爱读源码的大都督7 小时前
Claude Code源码分析(三):为什么系统提示词中需要有tools呢?
前端·人工智能·后端
爱勇宝7 小时前
Claude Code 被曝暗藏“隐形检测”代码:封代理不是最可怕的,可怕的是你根本不知道它在干什么
前端·后端·程序员
小牛不牛的程序员7 小时前
我用 Claude Code 半天撸完了一个完整网站,AI 编程到底提升了多少效率?
前端
东风破_7 小时前
JavaScript 面试常考的字符串算法:从反转字符串到回文判断
前端·javascript