generated at
useReducer
reducerのhooks



複雑になったらuseReducerを使おう、って説明になってないでしょmrsekut
「複雑になったら」ってなんやねん
本質をついている感じがしないので腑に落ちない
useStateが先にあって、複雑になるならuseReducer、ではなくまずuseReducerの使用を検討する



ts
const [state, dispatch] = useReducer(reducer, initialArg, init);
第1引数
reducer
type Reducer<S, A> = (prevState: S, action: A) => S;
例.ts
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(); } }
第2引数
stateの初期値
第3引数
初期値を遅延初期化するために使う関数
useStateの引数に関数を渡すのと同じイメージ
初期stateは init(initialArg) の結果になる




コード例
ts
type State = { count: number; }; type Action = { type: 'increment' | 'decrement'; }; function init(initialCount: number): State { return { count: initialCount }; } function reducer(state: State, action: Action): State { switch (action.type) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; default: throw new Error(); } } type CounterProps = { initialCount: number; }; const Counter: React.FC<CounterProps> = ({ initialCount }) => { const [state, dispatch] = React.useReducer(reducer, initialCount, init); return ( <> Count: {state.count} <button onClick={() => dispatch({ type: 'decrement' })}>-</button> <button onClick={() => dispatch({ type: 'increment' })}>+</button> </> ); };





useReducerを使うことで、状態がreducerの中に閉じる
それによって、 useCallback などのdepsにstateを入れずに済むため、パフォ改善につながる