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

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

相关推荐
蓝瑟忧伤3 小时前
前端技术新十年:从工程体系到智能化开发的全景演进
前端
Baklib梅梅3 小时前
员工手册:保障运营一致性与提升组织效率的核心载体
前端·ruby on rails·前端框架·ruby
IT_陈寒3 小时前
Redis性能翻倍的5个冷门技巧,90%开发者都不知道第3个!
前端·人工智能·后端
jingling5555 小时前
vue | 在 Vue 3 项目中集成高德地图(AMap)
前端·javascript·vue.js
油丶酸萝卜别吃5 小时前
Vue3 中如何在 setup 语法糖下,通过 Layer 弹窗组件弹出自定义 Vue 组件?
前端·vue.js·arcgis
J***Q29211 小时前
Vue数据可视化
前端·vue.js·信息可视化
ttod_qzstudio13 小时前
深入理解 Vue 3 的 h 函数:构建动态 UI 的利器
前端·vue.js
_大龄13 小时前
前端解析excel
前端·excel
一叶茶14 小时前
移动端平板打开的三种模式。
前端·javascript
前端大卫14 小时前
一文搞懂 Webpack 分包:async、initial 与 all 的区别【附源码】
前端