Reducer 這個概念,
來源於 React 的延伸套件 Redux,
其核心由 React 拿來參考後,
開發出了 React 原生 API ── useReducer。
所謂 Reducer 就是用模組化方式
自訂處理、改變數據的一套邏輯,
useState 的底層即是以 useReducer 實踐,
可視為擴充版的 useState。
useReducer 核心要素
基本上與 Redux 完全相同
Reducer 必須是 pure function,不得處理有副作用的行為,以確保每次計算結果都相同。
const [state, dispatch] = useReducer(reducer, initialState, init?)
參數
返回值
useState
),接受 action 作為參數const initialState = {count: 0};
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, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
const [state, dispatch] = useReducer(
reducer,
{count: initialCount}
);
傳入 init function 作為第三個參數,
初始 state 會是 init function 的回傳值。
function init(initialCount) {
return {count: initialCount};
}
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
case 'reset':
return init(action.payload);
default:
throw new Error();
}
}
function Counter({initialCount}) {
const [state, dispatch] = useReducer(reducer, initialCount, init);
return (
<>
Count: {state.count}
<button
onClick={() => dispatch({type: 'reset', payload: initialCount})}>
Reset
</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
這可以將初始 state 的計算邏輯
提取到之外 reducer 之外,
也方便處理重置 state 的 action。