useReducerを使った状態管理
React Hooksは、関数コンポーネントで状態やライフサイクルを扱うための素晴らしいツールを提供しています。useReducer
はその中でも特に複雑な状態管理において強力な手段となります。この記事では、useReducer
の基本的な使い方を解説します。
1. useReducerの基本
useReducer
は、状態を管理するための関数です。通常、コンポーネント内で複雑な状態を管理する場合や、状態の更新ロジックが複雑な場合に利用されます。基本の使い方を見てみましょう。
import { Reducer } from "react";
interface State {
count: number;
}
interface Action {
type: "INCREMENT" | "DECREMENT";
}
const reducer: Reducer<State, Action> = (state, action) => {
switch (action.type) {
case "INCREMENT":
return { count: state.count + 1 };
case "DECREMENT":
return { count: state.count - 1 };
default:
return state;
}
};
export default reducer;
import React, { useReducer } from "react";
import reducer from "./Reducer";
const Counter: React.FC = () => {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: "INCREMENT" })}>Increment</button>
<button onClick={() => dispatch({ type: "DECREMENT" })}>Decrement</button>
</div>
);
};
export default Counter;
2. useReducerとContextを組み合わせる
useReducer
をContextと組み合わせることで、グローバルな状態管理が可能です。これにより、複数のコンポーネントで同じ状態を参照することができます。
import { Reducer } from "react";
export interface State {
count: number;
}
export interface Action {
type: "INCREMENT" | "DECREMENT";
}
const reducer: Reducer<State, Action> = (state, action) => {
switch (action.type) {
case "INCREMENT":
return { count: state.count + 1 };
case "DECREMENT":
return { count: state.count - 1 };
default:
return state;
}
};
export default reducer;
import { ReactNode, createContext, useReducer } from "react";
import reducer, { Action, State } from "./Reducer";
interface CounterContextProps {
state: State;
dispatch: React.Dispatch<Action>;
}
export const CounterContext = createContext<CounterContextProps | undefined>(
undefined
);
const initialState = { count: 0 };
const CounterProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<CounterContext.Provider value={{ state, dispatch }}>
{children}
</CounterContext.Provider>
);
};
export default CounterProvider;
import React, { useContext } from "react";
import { CounterContext } from "./CounterProvider";
const CounterControls: React.FC = () => {
const { dispatch } = useContext(CounterContext)!; // 非nullアサーション演算子
return (
<div>
<button onClick={() => dispatch({ type: "INCREMENT" })}>Increment</button>
<button onClick={() => dispatch({ type: "DECREMENT" })}>Decrement</button>
</div>
);
};
export default CounterControls;
import React, { useContext } from "react";
import { CounterContext } from "./CounterProvider";
const Counter: React.FC = () => {
const { state, dispatch } = useContext(CounterContext)!; // 非nullアサーション演算子
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: "INCREMENT" })}>Increment</button>
<button onClick={() => dispatch({ type: "DECREMENT" })}>Decrement</button>
</div>
);
};
export default Counter;
3. useReducerの利点
-
複雑な状態管理:
useReducer
は状態の複雑なロジックを分離しやすくします。これによりコンポーネントがより単純で理解しやすくなります。 -
グローバルな状態管理: Contextと組み合わせることで、グローバルな状態管理が容易になります。異なる階層のコンポーネントで同じ状態を使用する場合に便利です。
-
可読性と保守性:
useReducer
を使うことで、コンポーネントが持つロジックがより一貫していて、保守性が向上します。
4. まとめ
useReducer
はReactアプリケーションにおいて、複雑な状態管理に対処するための強力なツールです。適切に利用することで、可読性や保守性を向上させつつ、柔軟で効率的なコードを記述することができます。
この記事では、初心者大学生がReact Nextを理解するためのアウトプット資料です。
間違いや意見などコメントお待ちしております!