React useReducer
React 中适合复杂状态转移场景的状态 Hook 及其与 useState 的边界。
#tech / dev / frame
#resource / react
#type / concept
#status / growing
[!info] related notes
- 所属 MOC: React MOC
- 上位主题: react-hooks, react
- 易混淆概念: react-use-state, React中的props、state和ref
React useReducer
useReducer 是 React 中管理复杂状态更新逻辑的 Hook。它更适合“状态如何变化”本身需要被清晰组织起来的场景。
一句话定义
当一个状态不是简单地改几个值,而是存在明确的动作类型和转移规则时,useReducer 往往比 useState 更清晰。
最小理解
state:当前状态dispatch:派发一个动作reducer:根据动作计算下一个状态
最小例子
type State = {
count: number
}
type Action =
| { type: 'increment' }
| { type: 'reset' }
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'increment':
return { ...state, count: state.count + 1 }
case 'reset':
return { ...state, count: 0 }
default:
return state
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 })
return (
<>
<button onClick={() => dispatch({ type: 'increment' })}>
{state.count}
</button>
<button onClick={() => dispatch({ type: 'reset' })}>
reset
</button>
</>
)
}
什么时候比 useState 更合适
- 表单状态很多,更新逻辑复杂
- 多个字段经常一起变化
- 你希望状态转移规则集中管理
- 组件像一个小型状态机
最典型的优势
- 更新逻辑集中
- 动作语义更明确
- 复杂状态更容易测试和追踪
什么时候该考虑从 useState 升级
如果你开始频繁写这种代码:
setState(prev => ({ ...prev, ... }))
setState(prev => ({ ...prev, ... }))
setState(prev => ({ ...prev, ... }))
而且不同事件会触发不同更新规则,这通常就是 useReducer 更合适的信号。
什么时候没必要上它
- 只是一个开关或一个输入框
- 更新逻辑非常直接,没有复杂分支
最短记忆方式
useState 更像“直接改值”,useReducer 更像“通过动作驱动状态转移”。