こんにちわ。
Reactには、useState の代替品となるuseReducer という機能があります。
複数の値にまたがる複雑な state ロジックがある場合に便利です。
簡単に言うと、複雑な値の更新にはuseReducerを使い、
簡単な値の更新にはuseState を使おうという感じでございます。
コードを見てみましょう。
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> </> ); }
こちらのコードを実行しますと、ボタンを押すことで現在のstateをdispatchを通して変更することができます。
見てお分かりの通り、useReducserとdispatchはセットで扱うものと覚えておきましょう。
初期stateの遅延
useReducerでは、stateの初期値の値を遅延させることができます。
その場合は、第三引数にinitと付け加えて、init関数を渡しましょう。
こうすることで、初期 state の計算をリデューサの外部に抽出することができます。これはアクションに応じて state をリセットしたい場合にも便利です。
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> </> ); }