useReducer
簡單來說就是 useState
進階用法。而且寫法上其實跟 Redux
差異不大。我們就直接來看範例吧
寫法如下:
const [state, dispatch] = useReducer(reducer, initialArg, init);
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() {
// 第一個參數:事件處理器,第二個參數 state Default Value
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
// state 只能透過 dispatch 方法改變
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
我們剛上面寫法中,並沒有用到第三個參數,而第三個參數作用就是傳入 init function 作為第三個參數。初始的 state 會被設定為 init(initialArg)。
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>
</>
);
}