React 中的函数式更新

React 中的函数式更新

React 中的函数式更新 ,指的是在更新 state 时,不给 setState 直接传新值,而是传一个函数 。这个函数会接收上一次最新的 state ,再基于它计算出新的 state。

基本写法

jsx 复制代码
setCount(prev => prev + 1);

这里的:

  • prev:上一次最新的状态值
  • prev + 1:基于旧值计算新值

为什么要用函数式更新?

因为 React 的状态更新可能是异步的、批量的

如果你直接这样写:

jsx 复制代码
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);

你以为会加 3,实际上很多情况下只会加 1。

因为这 3 次拿到的 count 很可能都是同一个旧值。

而函数式更新:

jsx 复制代码
setCount(prev => prev + 1);
setCount(prev => prev + 1);
setCount(prev => prev + 1);

React 会按顺序执行:

  • 第一次:0 -> 1
  • 第二次:1 -> 2
  • 第三次:2 -> 3

这样结果才是对的。


什么时候特别适合用?

1. 新状态依赖旧状态

最典型。

jsx 复制代码
setAge(prev => prev + 1);
setList(prev => [...prev, newItem]);

2. 连续多次更新同一个状态

jsx 复制代码
setCount(prev => prev + 1);
setCount(prev => prev + 1);

3. 异步回调里更新状态

比如:

  • setTimeout
  • Promise
  • useEffect
  • 事件订阅回调
jsx 复制代码
setTimeout(() => {
  setCount(prev => prev + 1);
}, 1000);

这样更安全,因为你拿到的是最新状态,不是闭包里的旧值。


对象状态中的函数式更新

如果 state 是对象,常见写法是:

jsx 复制代码
setState(prev => ({
  ...prev,
  count: 10
}));

含义是:

  • 先把旧对象展开
  • 再覆盖你要修改的字段

例如:

jsx 复制代码
const [user, setUser] = useState({
  name: 'Tom',
  age: 20
});

setUser(prev => ({
  ...prev,
  age: 21
}));

结果:

jsx 复制代码
{ name: 'Tom', age: 21 }

为什么不能直接改原对象?

jsx 复制代码
user.age = 21;
setUser(user);

这样是直接修改原对象,引用没变,React 可能识别不到变化。

而函数式更新通常配合不可变写法

jsx 复制代码
setUser(prev => ({
  ...prev,
  age: 21
}));

会返回一个新对象,React 更容易正确触发更新。


一句话理解

函数式更新就是:

"别相信你手里的旧 state,找 React 要最新的 state,再算出新值。"


什么时候用普通写法,什么时候用函数式更新?

普通写法

当新值不依赖旧值时可以直接写:

jsx 复制代码
setTheme('dark');
setVisible(true);

函数式更新

当新值依赖旧值时,优先用:

jsx 复制代码
setCount(prev => prev + 1);
setItems(prev => [...prev, item]);

总结

公式记住就行

  • 不依赖旧状态:直接传值
  • 依赖旧状态:传函数

最常见示例

jsx 复制代码
setCount(prev => prev + 1);
setList(prev => [...prev, newItem]);
setState(prev => ({ ...prev, loading: false }));

转载:https://www.toutiao.com/item/7626739884350390830/

相关推荐
Richown2 天前
React 高级模式:并发渲染下的状态机驱动架构——从 Finite State Machine 到生产级实现
区块链·react
LayZhangStrive3 天前
Agent开发 - 实现人类与Manus智能体的终端窗口命令交互
ai·交互·agent·react·终端·manus
名字还没想好☜4 天前
React 实现暗黑模式切换:localStorage 持久化、SSR 首屏闪烁与跟随系统主题
前端·javascript·react.js·ecmascript·react·next.js
ZGG0039 天前
真题拆解 05:ReAct 还是 Plan-and-Execute——规划范式怎么选
python·agent·react
eokred11 天前
图片预览组件的另一种设计:Headless、可组合、开箱即用
前端·react
ylj_dev14 天前
从 0 构建 AI Workload Platform(九):真实场景、最小控制台与开源发布
go·react·开源项目·工作流·ai agent
星辰徐哥14 天前
打破社媒营销信息差:具身交互智能打造全自动化KOL情报体系
运维·python·自动化·交互·react·数字人
Richown14 天前
Three.js 供应链三维可视化:全球物流轨迹、库存热力图与数字孪生的交互呈现
区块链·react
前端技术官14 天前
Web Components 为什么火不起来?
react·web components·ssr·shadow dom·custom elements
钛态14 天前
Vite 中的 CSS 工程化:从 CSS Modules 到 UnoCSS 的渐进式迁移
前端·vue·react·web