LoginSignup
1
0

useReducerを使った状態管理

React Hooksは、関数コンポーネントで状態やライフサイクルを扱うための素晴らしいツールを提供しています。useReducerはその中でも特に複雑な状態管理において強力な手段となります。この記事では、useReducerの基本的な使い方を解説します。

1. useReducerの基本

useReducerは、状態を管理するための関数です。通常、コンポーネント内で複雑な状態を管理する場合や、状態の更新ロジックが複雑な場合に利用されます。基本の使い方を見てみましょう。

Reducer.tsx
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;
Counter.tsx
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と組み合わせることで、グローバルな状態管理が可能です。これにより、複数のコンポーネントで同じ状態を参照することができます。

Reducer.tsx
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;
CounterProvider.tsx
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;
CounterControls.tsx
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;
Counter.tsx
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を理解するためのアウトプット資料です。
間違いや意見などコメントお待ちしております!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0