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/

相关推荐
喵了几个咪5 小时前
Headless 架构优势:内容与展示解耦,一套 API 打通全端生态
vue.js·架构·golang·cms·react·taro·headless
ZHENGZJM1 天前
架构总览:Monorepo 结构与容器化部署
架构·go·react·全栈开发
最初的↘那颗心1 天前
Agent 核心原理:本质、ReAct 框架与工具设计最佳实践
大模型·agent·react·spring ai·工具设计
一只小阿乐2 天前
TypeScript中的React开发
前端·javascript·typescript·react
Java码农也是农2 天前
ReAct vs Plan-and-Execute:哪种Agent架构更适合你的场景
react·plan+execute
这是个栗子3 天前
TypeScript(三)
前端·javascript·typescript·react
最初的↘那颗心3 天前
Prompt高级推理:COT思维链、Self-Consistency与ReAct模式实战
大模型·prompt·react·cot·思维链
起来改bug5 天前
【AiAgent学习】Agent中的ReAct模式
学习·react·aiagent入门
ん贤5 天前
ReAct Agent 与 Agent 编排:从单 Agent 闭环到多 Agent 协作(纯享版)
人工智能·ai·agent·react