✋
【React】普段よくuseStateを使ってるけど、useReducer使いたくなった✋
上記ドキュメント、zennを参考にしました。 useReducer使いたくなりました! 感謝です!
useReducerは useState
の代替品で、useStateと同じようにコンポーネントを状態管理できるようになります。
useReducerを使うべき条件
複数の値にまたがる複雑な state ロジックがある場合や、前の state に基づいて次の state を決める必要がある場合
useReducerを使うメリット
コールバックの代わりに dispatch を下位コンポーネントに渡せるようになる
ステイトの更新ロジックを分離することができる
reducerの単体テストが可能になる
useReducerを使った具体例
- checkboxのvalueを配列(State)に保存する。
- 配列の要素がダブらないように、ステイトを更新する際に適宜条件分岐を行いユニークな状態を保つ。
checkbox_useReducer.js
import React, { useReducer } from "react";
import Checkboxes from "../components/checkboxes";
import reducer from "../lib/function/checkboxReducer";
const checkbox_useReducer = () => {
const [checkboxState, dispatch] = useReducer(reducer, []);
return <Checkboxes clickCheckBox={dispatch} />;
};
export default checkbox_useReducer;
checkboxReducer
const reducer = (state, action) => {
if (state.includes(action)) {
return (state = state.filter((item) => item != action));
} else {
return (state = [...state, action]);
}
};
export default reducer;
checkboxes.js
import React, { memo } from "react";
const Checkboxes = ({ clickCheckBox }) => {
return (
<div>
<label>jordan1</label>
<input
type="checkbox"
value="jordan1"
onChange={(e) => clickCheckBox(e.target.value)}
/>
<label>jordan2</label>
<input
type="checkbox"
value="jordan2"
onChange={(e) => clickCheckBox(e.target.value)}
/>
<label>jordan3</label>
<input
type="checkbox"
value="jordan3"
onChange={(e) => clickCheckBox(e.target.value)}
/>
</div>
);
};
export default memo(Checkboxes);
コールバック関数を子コンポーネント(memo化している状態)に渡すと、例えコールバック関数の処理が同じだったとしても、違う関数と判断されてしまいます。しかしdispatchの場合
再レンダー間で dispatch 関数の同一性が保たれ、変化しないことを保証します。
上記のようにドキュメントに記載があり、dispatchを渡す子コンポーネントでmemo化を行うことで無駄なレンダリングを防ぐことができます。
Discussion