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/

相关推荐
JudithHuang8 天前
React 嵌套路由与布局
前端·react.js·arcgis·react·react router
2601_9679873711 天前
Next.js 全栈开发入门指南(2026 最新版)
react·next.js·全栈开发·企业级开发·渲染模式
2601_9679873711 天前
完整教程:Next.js项目演示(从零创建Next.js项目)Next.js入门实战
react·教程·前端开发·next.js·项目创建
goehou12 天前
ReAct 循环跑偏的三种样子,以及怎么在工程上兜住
llm·agent·react·工具调用·工程实践
大连好光景13 天前
ClaudeCode有关Agent Loop知识点大全
react·max_turns·agentloop·checkpoint快照·流式输入
汤米粥13 天前
2026年主流前端技术框架
vue·react·elementplus·tailwind css·angular‌·svelte‌·bootstrap‌
2601_9679873714 天前
Next.js 文档
react·开发·全栈·文档·next.js
前进的李工14 天前
Agent 学习笔记 01:从工具调用到 ReAct 循环
笔记·学习·llm·agent·react·工具调用
Oiiouui15 天前
关于 Logto 登录系统的体验以及建议
javascript·安全·react