别让状态把你折磨得像状态一样复杂。
前言
如果你是这样的小白:
- 用
useState用得飞起,但状态一多就开始写props传到怀疑人生; - 老板跟你说:“咱要不要上个 Redux?” 你一脸问号:
useContext不行吗?useReducer又是啥?
别慌,这篇文章就是你的“救命顺风车”:
- 带你用最简单的示例,搞懂
useReducer和useState有啥区别; - 让你知道为什么它被称作 “简易 Redux”;
- 最后还能抄一份“可跑 Demo”到自己项目里,管理多状态爽到飞起!
🐣 useState 能干嘛?为啥还要 useReducer?
useState 很好用,小而美:
const [count, setCount] = useState(0);
简单场景:按钮点一下 +1,完美。
可一旦你状态一多,比如:
isLogin:登录态theme:暗黑/明亮模式todos:代办事项列表count:页面点击次数age:用户年龄
你就得写一堆 useState,传来传去,props drilling(钻头传递)转到手抖。
这时,useReducer 出场了。
useReducer:useState 的加强版
官方解释:
useReducer是useState的替代方案,用于更复杂的状态逻辑。
一句话:
✅ 多状态、相互依赖、需要统一修改,就该用 useReducer。
一个最简单的例子:从 useState 到 useReducer
看懂下面这个例子,你就赢了:
const [state, dispatch] = useReducer(reducer, initialState);
拆开说:
| 名字 | 意义 |
|---|---|
state | 当前状态(可以是对象) |
dispatch | 派发“状态修改命令” |
reducer | 纯函数,告诉状态怎么改 |
initialState | 初始值 |
对比 useState:
const [count, setCount] = useState(0);
你只能一个状态一个钩子。
但 useReducer 可以这样:
const initialState = {
count: 0,
age: 21
};
然后所有状态都放 state 里,改就用 dispatch。
高级得像小型 Redux。
reducer:状态管理的灵魂
reducer 这个词很玄乎,其实就是个纯函数,干一件事:
(纯函数是什么我这里便不再详细介绍哦,如果有需要可以看看其他文章或者问问ai)
相同输入,一定相同输出,且不搞副作用!
官方约束:
- 不能发请求
- 不能改 DOM
- 不能偷偷改外部变量
只负责把:
新状态 = reducer(旧状态, action)
像个生产线工厂,扔什么料(action),产什么货(state)。
实战示例:多状态管理 + 派发命令
下面,咱们直接上代码,我来帮你理理思路
import {
useState,
useReducer
} from 'react';
import './App.css';
// ---------------------------
// 定义初始状态
const initialState = {
count: 0,
age: 21
};
// ---------------------------
// 定义 reducer:纯函数,状态工厂
const reducer = (state, action) => {
switch (action.type) {
case 'increment':
return {
count: state.count + 1,
age: state.age + 1
};
case 'decrement':
return {
count: state.count - 1,
age: state.age - 1
};
case 'incrementByNum':
return {
...state,
count: state.count + Number(action.payload)
};
default:
return state;
}
};
// ---------------------------
// App 组件
function App() {
const [input, setInput] = useState(0); // 控制 input 输入
// useReducer:旧状态 + dispatch 派发
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
<h2>Count: {state.count}</h2>
<h2>wcy的Age: {state.age}</h2>
<button onClick={() => dispatch({ type: 'increment' })}>+1</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-1</button>
<br /><br />
<input
type="number"
value={input}
onChange={e => setInput(e.target.value)}
/>
<button onClick={() => dispatch({ type: 'incrementByNum', payload: input })}>
加上输入的数字
</button>
</>
);
}
export default App;
🧩 核心点拆解
✅ 初始状态 initialState
initialState 就是一份“状态清单”,它把你要用的所有状态集中放在一个对象里,比如页面上的数字、用户年龄、是否登录、主题颜色……都能放进去。
这样做的好处是:状态都在一块,方便管理、方便看,也方便后期扩容。以后要新增状态,直接在 initialState 里加字段就行,整个状态树一目了然。
✅ reducer
reducer 是整个状态管理的大脑,它是一个纯函数,唯一职责是:
根据输入(旧状态 + action),计算并返回新的状态。
它不会做多余的事,比如网络请求、改外部变量、改页面元素,这叫“没有副作用”,这样状态就特别可靠可预测,不容易出 bug。
想改状态,只能通过 reducer 里定义好的“规则”来改,这就是它可控、可维护的核心原因。
✅ dispatch
dispatch 可以理解成“指挥棒”,谁要改状态都得先通过它发出“命令”,这个命令就是 action(带 type 和可选的参数 payload)。
dispatch 自己不会直接改状态,它只负责把这条指令交给 reducer,由 reducer 按规则生产新的状态,然后交给 React 去重新渲染。
所以:谁改状态,流程清晰;要改啥,全程可追溯。
✅ 多状态同时管理
在实际开发里,一个页面往往不是只有一个状态,比如点个按钮会改多个值,像“点赞数 +1 的同时,用户积分 +10”。
用 reducer 管理时,这些状态都在一个地方,彼此依赖也没关系,只要在同一个 case 里写清楚就好,所有状态变动都由同一个大脑统筹,多状态之间的逻辑关系就能清清楚楚,不会乱套。
✅ 界面由状态驱动
最妙的一点是:只要状态变了,React 会自动重新渲染相关的地方。
也就是说,你只管专心用 dispatch 改状态,别动别的,界面更新这件事 React 会帮你兜底,不会有“状态改了但是页面没变”的情况。
整个思路就是“数据驱动视图”,状态是源头,界面只是结果,维护起来特别省心。
🌟 这 5 个点串起来,就是 useReducer 的核心哲学:
所有状态集中管理 → 用纯函数可靠计算 → 用
dispatch统一触发 → 多状态一起管理 → 视图自动响应
懂了这套思路,你就能把 useReducer 玩得比 useState 更灵活,还能平滑过渡到更大规模的状态管理(比如配合 useContext、再到 Redux),从此告别混乱状态,面试吹起来也底气十足!
用 useReducer 和 Redux 有啥关系?
useReducer = 迷你版 Redux
-
reducer概念一样:纯函数,状态工厂 -
dispatch概念一样:统一派发命令 -
只是
useReducer没有:- 全局中间件(比如
thunk) - 时间旅行(Redux DevTools)
- 分模块拆分 reducer(可组合)
- 跨组件
context(需要useContext一起用)
- 全局中间件(比如
所以,很多面试官会问:
“有了
useReducer+useContext,为啥还要 Redux?”
✅ 小型项目就够了,省事。
✅ 大型项目状态复杂、有异步流、需要多人协作调试?上 Redux 更香。
小结一句话
useReducer本质就是帮你写了个小型状态机,
所有的状态都按纯函数来生产,
这样你的状态可预测、可回放、可维护。
🎉 面大厂的思维点
如果有面试官考你:
“为什么要纯函数?”
你可以斩钉截铁:
“相同输入,输出可预测。没有副作用,状态可调试、可追溯,这就是状态管理的根本价值。”
然后举个例子:
“Redux 的
reducer就是纯函数。useReducer也一样。状态生产器嘛!”
这时候,面试官嘴角上扬,你已经赢了一半。
写在最后
useReducer 是你从 useState 升级到 Redux 的必经之路。
记住这条成长线:
useState → useReducer → useReducer + useContext → Redux → Redux + 中间件
一步步来,你就会从状态小白,成长为状态大师。
如果你觉得有用,点个赞 ❤️ + 收藏 🏷️,让更多刚学 React 的同学少踩坑,也欢迎评论区分享你的“状态管理血泪史”!
作者:wcy的状态工厂
用最简单的语言,写最靠谱的代码。