useReducer
面试速答(30 秒版 TL;DR)
useReducer是另一种状态管理方式,适合状态转移逻辑复杂、多个分支共享同一套更新规则的场景。- 它的核心不是“更高级的
useState”,而是把“状态怎么变”统一收口到 reducer。 - 特别适合:
- 多个 action 驱动同一状态对象
- 状态流转比较明确
- 想把更新逻辑做成可测试的纯函数
- React 18 里它仍是同步描述状态变更规则的 Hook,并不会自动变成全局状态管理。
1. 基本模型
useState 更像:
- 我直接设置一个值
useReducer 更像:
- 我派发一个动作
- reducer 决定状态该怎么变
示例:
type Action =
| {type: 'increment'}
| {type: 'decrement'}
function reducer(state: number, action: Action) {
switch (action.type) {
case 'increment':
return state + 1
case 'decrement':
return state - 1
default:
return state
}
}
const [count, dispatch] = useReducer(reducer, 0)
2. 它适合什么场景
2.1 多分支状态更新
比如一个表单编辑器可能有:
- 更新字段
- 重置
- 批量填充
- 提交成功回写
如果全用多个 setState 分散写,逻辑容易散。
2.2 状态机味道更强的流程
例如:
idleloadingsuccesserror
这种“动作驱动状态流转”的问题,很适合 reducer 思维。
3. 为什么说 reducer 要尽量保持纯函数
reducer 最理想的形式是:
- 输入旧状态和 action
- 返回新状态
- 不做副作用
这样有几个好处:
- 更好测
- 更容易复盘状态流转
- 逻辑集中,不容易散到各处
副作用通常应该放在:
- 事件处理函数
useEffect
而不是 reducer 里。
4. useReducer 和 useState 怎么选
4.1 用 useState 更合适的时候
- 状态很简单
- 只有一两种更新方式
- 不需要统一动作模型
4.2 用 useReducer 更合适的时候
- 多个更新入口
- 状态逻辑越来越复杂
- 多个字段之间有关联
5. React 18 面试高频答法
Q1:为什么 useReducer 适合复杂状态?
因为它把“更新规则”集中在 reducer,而不是散落在多个事件处理函数里。
Q2:它能替代 Redux 吗?
在局部组件状态范围内可以承担一部分角色,但它不自带:
- 全局共享
- DevTools
- 中间件
- 跨模块组织
所以它不是 Redux 的完整替代品。
Q3:dispatch 为什么常被认为比较稳定?
因为 React 会提供稳定的派发入口,这让它在依赖传递和 Context 组合时比较方便。
常见追问
1)可以配合 Context 用吗?
可以。常见做法就是 useReducer + useContext 组成一个轻量局部状态容器。
2)初始化很重怎么办?
可以用惰性初始化,把初始计算延后到首次需要时。
易错点/坑
- reducer 里写副作用。
- 明明状态很简单,也强上
useReducer,导致样板代码变多。 - 把它误解成“天然全局状态管理”。
速记要点(可背诵)
useReducer:把状态更新规则收口到 reducer。- 适合复杂状态流转,不适合所有简单本地状态。
- reducer 尽量保持纯函数,副作用放外面。