在 React 开发中,组件的状态管理是重中之重。绝大多数场景下,我们会用最原生的 useState
,因为它简洁、直观。但当状态复杂或多个状态之间有依赖、联动时,useReducer
就能发挥更大的作用。
1. 什么是 reducer?
reducer 的概念最早来自于函数式编程和 Redux。它本质上是一个"状态转换函数":
nextState = reducer(currentState, action)
- reducer 是一个纯函数,它接收当前状态 (
currentState
) 和一个描述"发生了什么"的动作对象 (action
),根据 action 的类型返回一个新的状态 (nextState
)。 - 通常写法如下:
javascript
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
2. useReducer 基本用法
useReducer
是 React 提供的一个 hook,用于用 reducer 模式管理组件状态。其基本格式为:
javascript
const [state, dispatch] = useReducer(reducer, initialState);
state
:当前的状态对象(可以很复杂,支持嵌套对象)dispatch
:用来"派发" action(动作),触发 reducer 执行并返回新状态reducer
:具体描述"各种情况下状态怎么变"的逻辑集中地写在 reducer 函数里initialState
:初始状态对象
3. 适合用 useReducer 的场景
- 多个状态需要一起更新(例如表单情况,或者复杂交互)
- 某个状态的改变取决于另一个状态
- 状态管理逻辑复杂,单用 useState 管理太难维护
- 希望让状态管理更声明式(更容易追踪、测试和扩展)
举例:
javascript
function reducer(state, action) {
switch (action.type) {
case 'setValue':
return { ...state, value: action.payload };
case 'reset':
return { ...state, value: '' };
default:
return state;
}
}
const [state, dispatch] = useReducer(reducer, { value: '' });
点击按钮时你只需写:dispatch({ type: 'setValue', payload: newValue })
,而不用手动一一 setX。
4. useReducer vs useState
- useState 适用于:状态简单、彼此独立,比如 hovering、selected 等互不影响的小状态。
- useReducer 适用于:多个状态有联动、更新互相依赖、状态管理逻辑需要集中统一。
5. 优点总结
- 让"状态怎么变"与"由什么触发"分离,逻辑统一集中。
- 可以在副作用(如 useEffect)中安全地 dispatch action,而不用把大量 state 变量加进依赖数组。
- 代码可读性强,易维护,方便扩展。
结语
useReducer 并不难上手,但当你遇到"状态更新有依赖或一起变更"时,它会让你的 React 代码更优雅、更易维护。如果是简单场景,就依然可以用 useState。