1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Reduxを公式ドキュメントを読みながら基本を思い出す

1
Last updated at Posted at 2026-06-29

最近、Reduxを使った既存コードを触る機会が多くありました。

久しぶりにReduxのコードを読むと、

  • store とは何だったか
  • statereducer の関係は何だったか
  • actiondispatch は何をしているのか
  • 画面操作から state 更新まで、どう流れているのか

といった各メソッドや概念の役割が、少し曖昧になっていました。

そこで今回は、Redux公式ドキュメントの説明を確認しながら、Reduxの基本を改めて整理します。

まずはReduxの基本的な考え方を思い出すことを目的にします。


Reduxとは

Redux公式の Getting Started with Redux では、Reduxは次のように説明されています。

Redux is a JS library for predictable and maintainable global state management.

日本語にすると、Reduxは「予測可能で保守しやすいグローバル状態管理のためのJavaScriptライブラリ」です。

つまりReduxは、アプリケーション内で共有する状態を、決められたルールで管理するための仕組みです。

Reactだけでも、コンポーネント内の状態は useState で管理できます。

const [keyword, setKeyword] = useState('');

この keyword が1つのコンポーネント内だけで使われるなら、useState で十分です。

しかし、アプリケーションが大きくなると、複数の画面やコンポーネントで同じ状態を使いたい場面が出てきます。

たとえば、次のような状態です。

  • ログイン中のユーザー情報
  • 検索条件
  • マスターデータ
  • ダイアログの表示状態
  • 通知メッセージ
  • APIから取得した共通データ

こうした状態を各コンポーネントでバラバラに管理すると、どこで値が変わったのか追いづらくなります。

Reduxでは、共有したい状態を store という場所にまとめ、actionreducer というルールを通して更新します。


Reduxが解決したいこと

Redux公式の Redux Fundamentals, Part 2: Concepts and Data Flow では、Reactの小さなカウンターを例に、アプリケーションには大きく次の3つがあると説明されています。

用語 役割
state アプリを動かす信頼できる状態
view 現在の state をもとにしたUI
actions ユーザー操作などによって発生し、state 更新のきっかけになる出来事

小さなコンポーネントであれば、useState だけでも十分です。

function Counter() {
  const [counter, setCounter] = useState(0);

  return (
    <button onClick={() => setCounter(counter + 1)}>
      {counter}
    </button>
  );
}

この例では、state も更新処理もコンポーネント内に閉じています。

しかし、複数のコンポーネントで同じ state を共有したくなると、話が少し複雑になります。

親コンポーネントに state を持ち上げる方法もありますが、コンポーネントの階層が深くなったり、離れた場所にあるコンポーネント同士で同じ state を使いたくなったりすると、propsの受け渡しがつらくなります。

Reduxの基本的な考え方は、共有したい state をコンポーネントツリーの外に置き、どのコンポーネントからでも参照・更新できるようにすることです。

ただし、自由にどこからでも書き換えるのではなく、決められた流れで更新します。


store・state・reducerの関係

Reduxを理解するときに、まず押さえたいのが storestatereducer の関係です。

ざっくり言うと、次のようになります。

用語 役割
store state を保存している箱
state 現在のデータ
reducer state を更新するためのルール

Redux公式の Getting Started with Redux では、アプリ全体のグローバル state は、単一の store 内にobject treeとして保持されると説明されています。

つまり、store はアプリケーション全体の状態を持つ場所です。

たとえば検索フォームの状態を考えると、state は次のようになります。

type SearchFormState = {
  keyword: string;
  isOpen: boolean;
};

この state は、現在の検索フォームの状態を表しています。

const initialState: SearchFormState = {
  keyword: '',
  isOpen: false,
};

一方、reducer はこの state をどう更新するかを決める関数です。

function searchFormReducer(state = initialState, action) {
  switch (action.type) {
    case 'searchForm/changeKeyword':
      return {
        ...state,
        keyword: action.payload,
      };

    default:
      return state;
  }
}

reducer は、現在の stateaction を受け取り、新しい state を返します。

reducer(currentState, action) => newState

ここで大事なのは、statereducer に何かを送っているわけではないということです。

Reduxの store が、現在の state とdispatchされた actionreducer に渡します。

そして reducer が返した新しい state を、store が保存します。

流れとしては次のようになります。

storeが現在のstateを持っている
↓
actionがdispatchされる
↓
storeがreducerに currentState と action を渡す
↓
reducerが newState を返す
↓
storeが newState を保存する

💡 ポイント

store は「状態を持つ場所」、state は「現在の中身」、reducer は「中身をどう変えるかのルール」と考えると分かりやすいです。


actionとは

Redux公式の Getting Started with Redux では、state を変更する唯一の方法は、何が起きたかを表す action を作り、それを storedispatch することだと説明されています。

action は、アプリケーション内で起きた出来事を表すオブジェクトです。

たとえば、検索キーワードが変更された場合は次のような action になります。

{
  type: 'searchForm/changeKeyword',
  payload: 'React'
}

この action は、次の出来事を表しています。

検索キーワードがReactに変更された

type は、何が起きたのかを表す名前です。

payload は、その action に必要な追加データです。

この例では、変更後のキーワードである 'React'payload に入っています。

action は「stateをどう変更するか」ではなく、「何が起きたか」を表すものです。

実際に state をどう変更するかは、後述する reducer が担当します。


dispatchとは

dispatch は、actionstore へ送る処理です。

dispatch({
  type: 'searchForm/changeKeyword',
  payload: 'React',
});

Reactの onClickonChange は、ブラウザ/React側のイベントです。

そのイベントをきっかけに、Reduxへ actiondispatch します。

<input
  value={keyword}
  onChange={(event) => {
    dispatch({
      type: 'searchForm/changeKeyword',
      payload: event.target.value,
    });
  }}
/>

つまり、Reduxでは画面から state を直接変更するのではなく、次の流れで state を更新します。

画面操作
↓
actionをdispatch
↓
reducerがstateを更新

💡 ポイント

onChange はReact側のイベント、action はReduxに渡す「アプリ内で何が起きたか」の情報です。


reducerとは

reducer は、現在の stateaction を受け取り、新しい state を返す関数です。

Redux公式の Getting Started with Redux では、reducer の関数シグネチャは次のように説明されています。

(state, action) => newState

たとえば、検索キーワードを更新する reducer は次のようになります。

const initialState = {
  keyword: '',
  isOpen: false,
};

function searchFormReducer(state = initialState, action) {
  switch (action.type) {
    case 'searchForm/changeKeyword':
      return {
        ...state,
        keyword: action.payload,
      };

    case 'searchForm/open':
      return {
        ...state,
        isOpen: true,
      };

    default:
      return state;
  }
}

この reducer は、次のようなルールを持っています。

  • searchForm/changeKeyword が来たら keyword を更新する
  • searchForm/open が来たら isOpentrue にする
  • それ以外なら現在の state をそのまま返す

Reduxでは、state を直接書き換えるのではなく、新しい state を返すのが基本です。

return {
  ...state,
  keyword: action.payload,
};

このように、既存の state をコピーしつつ、変更したい値だけを差し替えます。

💡 ポイント

Reduxの基本では、state を直接変更せず、新しい state を返すことが重要です。


Reduxの一方向データフロー

Reduxの基本的な流れは、一方向です。

Redux公式の Redux Fundamentals, Part 2: Concepts and Data Flow では、state が特定時点のアプリ状態を表し、UIはその state に基づいて描画され、ユーザー操作などが起きると state が更新され、新しい state に基づいてUIが再描画されると説明されています。

図にすると、次のような流れです。

state
↓
view
↓
action
↓
reducer
↓
new state
↓
view

もう少しReactの画面操作に寄せると、次のようになります。

storeにstateがある
↓
Reactがstateをもとに画面を表示する
↓
ユーザーが入力・クリックする
↓
actionをdispatchする
↓
reducerが新しいstateを返す
↓
storeのstateが更新される
↓
Reactが再描画される

Reduxの良いところは、state 更新の流れが一本道になっていることです。

どこかで突然値が変わるのではなく、actiondispatch し、reducer を通して state が更新されます。

そのため、既存コードを読むときも、次の順番で追うことができます。

  1. どの actiondispatch されたのか
  2. どの reducer が処理したのか
  3. どの state が変わったのか

selectorとは

selector は、storestate から必要な値を取り出す関数です。

たとえば、検索キーワードを取り出す selector は次のようになります。

const selectKeyword = (state: RootState) =>
  state.searchForm.keyword;

Reactコンポーネントでは、React Reduxの useSelector を使って値を取得できます。

const keyword = useSelector(selectKeyword);

React Redux公式の Hooks では、useSelector はRedux storeの state から値を取り出すためのフック、useDispatchdispatch 関数を取得するためのフックとして説明されています。

useDispatch を使うと、コンポーネント内から actiondispatch できます。

const dispatch = useDispatch();

dispatch({
  type: 'searchForm/changeKeyword',
  payload: 'React',
});

selector を見ると、そのコンポーネントがRedux storeのどの値に依存しているか分かります。

既存コードを読むときは、useSelectormapStateToProps を探すと、画面がどの state を参照しているかを追いやすくなります。


Redux Toolkitについて少しだけ触れる

Reduxの基本概念を理解するうえでは、actionreducerstore の関係を押さえることが大事です。

ただし、現在のReduxではRedux Toolkitを使う書き方が公式に推奨されています。

Redux公式の Getting Started with Redux では、Redux ToolkitはReduxロジックを書くための公式推奨アプローチと説明されています。

Redux Toolkitを使うと、configureStorecreateSlice を使って、store設定やreducer/actionの定義を簡潔に書けます。

Redux Toolkit公式の createSlice は、slice名、初期 state、reducer関数群を受け取り、action creatorとaction typeを自動生成するAPIです。

const searchFormSlice = createSlice({
  name: 'searchForm',
  initialState: {
    keyword: '',
  },
  reducers: {
    changeKeyword(state, action) {
      state.keyword = action.payload;
    },
  },
});

このコードでは一見 state を直接変更しているように見えます。

state.keyword = action.payload;

しかしRedux Toolkitでは内部でImmerが使われており、実際にはimmutable updateとして処理されます。

この記事では、Redux Toolkitの細かい使い方には入りません。

まずは、Reduxの基本的な流れを理解することを優先します。

💡 ポイント

現在Reduxを新しく書く場合は、Redux Toolkitを使うのが公式推奨です。

ただし、既存コードを読むためには、actiondispatchreducerstore の基本概念を理解しておくことが大切です。


既存コードを読むときの順番

Reduxの既存コードを読むときは、次の順番で見ると理解しやすいです。

  1. store にどの reducer が登録されているかを見る
  2. 対象機能の state の形を見る
  3. useSelector / mapStateToProps で参照している値を見る
  4. dispatch している箇所を見る
  5. actiontypepayload を見る
  6. reducerstate がどう更新されるかを見る

いきなりすべてのファイルを理解しようとすると大変です。

まずは1つの入力項目やボタンを選び、次の観点で追うとReduxの流れが見えやすくなります。

  • この値はどこから来ているのか
  • どの操作で更新されるのか
  • どの reducer で処理されるのか

Reduxは最初に全体を見ようとすると少し構えてしまいますが、1つの値を追いかけると急に読みやすくなります。

迷子になったら、まず dispatch を探す。Redux散歩の基本です。


まとめ

今回は、Redux公式ドキュメントを確認しながら、Reduxの基本を整理しました。

Reduxは、アプリケーション全体で共有する状態を store に置き、actiondispatch し、reducer で新しい state を作る仕組みです。

重要なのは、state を直接変更するのではなく、次の流れで更新することです。

dispatch(action)
↓
reducer(currentState, action)
↓
newState
↓
storeに保存
↓
画面が再描画される

Reduxの基本用語を整理すると、次のようになります。

用語 役割
store state を保存している場所
state 現在のデータ
action 何が起きたかを表すオブジェクト
dispatch actionstore へ送る処理
reducer 現在の stateaction から新しい state を作る関数
selector state から必要な値を取り出す関数

Reduxのコードを読むときは、まずこの流れを頭に置いておくと理解しやすくなります。

次回は、action creatorや非同期処理を見ながら、既存プロジェクトでReduxのコードをどう追っていくかを整理します。


参考リンク

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?