useReducer
是 React 中用于管理復雜狀態邏輯的 Hook,它通過 集中式狀態更新邏輯 替代 useState
,尤其適合處理多值關聯狀態或依賴前序狀態更新的場景。以下是其核心要點:
1. 核心概念
- Reducer 模式:靈感來自 JavaScript 的
Array.prototype.reduce
和 Redux,通過(state, action) => newState
函數管理狀態變更。 - 返回值:返回當前狀態
state
和派發函數dispatch
,例如:const [state, dispatch] = useReducer(reducer, initialState);
2. 參數解析
參數 | 說明 |
---|---|
reducer | 純函數,接收當前狀態和 action ,返回新狀態。常用 switch/case 處理不同 action.type 。 |
initialState | 初始狀態值(如 { count: 0 } )。 |
init函數 | (可選)惰性初始化,將初始狀態計算邏輯封裝(如從 localStorage 讀取)。 |
3. 工作流程
- 派發 Action:調用
dispatch({ type: 'increment' })
觸發狀態更新。 - Reducer 處理:根據
action.type
計算新狀態(需返回全新對象,不可直接修改原狀態)。 - 組件渲染:狀態更新后組件重新渲染。
4. 對比 useState
特性 | useReducer | useState |
---|---|---|
適用場景 | 復雜邏輯、多關聯狀態 | 簡單獨立狀態 |
代碼組織 | 邏輯集中,易于維護 | 邏輯分散在多個 setState |
性能優化 | 可避免深層傳遞回調 | 需手動優化 |
5. 典型示例
計數器應用
function reducer(state, action) {switch (action.type) {case 'increment':return { count: state.count + 1 };case 'decrement':return { count: state.count - 1 };default:throw new Error();}
}function Counter() {const [state, dispatch] = useReducer(reducer, { count: 0 });return (<>Count: {state.count}<button onClick={() => dispatch({ type: 'increment' })}>+</button></>);
}
惰性初始化
function init(initialCount) {return { count: initialCount };
}function reducer(state, action) {// ...同上
}function Counter({ initialCount }) {const [state, dispatch] = useReducer(reducer, initialCount, init);// ...
}
6. 使用場景
- 復雜狀態對象:如表單、多步驟向導。
- 性能敏感場景:避免子組件不必要的渲染(通過傳遞
dispatch
而非回調)。 - 狀態依賴前值:如
state.count + action.payload
。
7. 注意事項
- 純函數要求:Reducer 必須無副作用,不直接修改
state
。 - 異步問題:
dispatch
后立即讀取state
仍是舊值(更新是異步的)。 - SSR 兼容:需注意服務端渲染時的初始化邏輯。
總結
useReducer
通過集中管理狀態變更邏輯,提升了代碼可維護性和可預測性,適合中大型應用的復雜狀態管理。結合 useContext
可進一步替代 Redux 等狀態庫。