😆
React Hooksの10種類を理解する(Additional: useReducer)
React Hooksの10種類を理解する(Basic: useReducer)
useReducer
とは
-
useReducer
は、useState
の代替品。 - 複数の値にまたがる複雑なstateロジックがある場合や、前のstateに基づいて次のstateを決める必要がある場合に使用。
-
(state, action) => newState()
というreducerを受け取り、現在のstateをdispatch
メソッドとペアにして返す。 - callbackの代わりに
dispatch
を下位コンポーネントに渡せるようになるので、パフォーマンスの最適化にもなる。
const [state, dispatch] = useReducer(reducer, initialArg, init);
useState
とuseReducer
との比較(公式より)
useState
の場合
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
</>
);
}
useReducer
の場合
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>
</>
);
}
useReducer
の初期化方法
初期stateを指定
const [state, dispatch] = useReducer(
reducer,
{count: initialCount}
);
遅延初期化
-
init
関数を第3引数として渡す(上記の「useReducer
の場合」がそれに当たる)
dispatchによる更新の回避
- 現在値のstateと同じ値を返した場合は、dispatchによって実行を回避して処理を終了する。
Discussion