0
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?

React初心者が覚えておきたい、useState以外の軽量状態管理を導入すべき5つのタイミング

0
Posted at

Reactのコンポーネントで最も基本的なのは useState ですが、規模が大きくなると 「どこで状態管理を切り替えるか」 が悩みどころです。この記事では、初心者が useState だけで抱えがちな課題 を把握し、軽量な代替手段(useReducer、Zustand、Jotai など)を 導入すべき具体的なタイミング を 5 つに絞って解説します。

1. 同一コンポーネントで状態が増えすぎたとき

useState を 10 個以上書くケースは少なくありません。

  • 症状: 変数名が増えてコードが読みにくい
  • 判断基準: 同じコンポーネント内で 3 つ以上のロジックが状態を共有する場合

対策: useReducer を使うと、状態遷移が一元管理でき、アクション名で意図が明確になります。

import React, { useReducer } from "react";

type State = { count: number; text: string };
type Action =
  | { type: "increment" }
  | { type: "decrement" }
  | { type: "setText"; payload: string };

const reducer = (state: State, action: Action): State => {
  switch (action.type) {
    case "increment":
      return { ...state, count: state.count + 1 };
    case "decrement":
      return { ...state, count: state.count - 1 };
    case "setText":
      return { ...state, text: action.payload };
    default:
      return state;
  }
};

export const Counter = () => {
  const [state, dispatch] = useReducer(reducer, { count: 0, text: "" });

  return (
    <>
      <p>{state.count}</p>
      <button onClick={() => dispatch({ type: "increment" })}>+</button>
      <button onClick={() => dispatch({ type: "decrement" })}>-</button>
      <input
        value={state.text}
        onChange={(e) => dispatch({ type: "setText", payload: e.target.value })}
      />
    </>
  );
};

2. 複数コンポーネントで同じ状態を共有したい

親子関係が深くなると props の掘り下げが頻発します。

  • 症状: 「props drilling」 が目立つ
  • 判断基準: 2 つ以上の子コンポーネントが同一状態を参照・更新する場合

対策: Zustand のようなシンプルなグローバルストアを導入すると、コンテキストや Redux のボイラープレートなしに共有できます。

3. 非同期ロジックと状態が絡むとき

API 呼び出しの結果を複数箇所で利用するケース。

  • 症状: ローディングやエラーハンドリングが散在する
  • 判断基準: 同一データ取得ロジックが 2 つ以上のコンポーネントで必要になるとき

対策: Jotai の atom と useAtom を組み合わせると、非同期関数を atom にラップでき、どこからでも同じデータにアクセス可能です。

4. 型安全を保ちつつ状態を拡張したい

TypeScript で型エラーが頻発する場合。

  • 症状: any を多用せざるを得ない
  • 判断基準: 状態オブジェクトに対して複数の型が混在し、型推論が失われるとき

対策: useReducer の型パラメータを活用すれば、アクションごとに厳密な型を定義でき、将来的なリファクタリングが楽になります。

5. パフォーマンスが気になるが、導入コストは抑えたい

大量のリストや頻繁な再レンダリングがボトルネックになるケース。

  • 症状: コンポーネントが不要に再描画される
  • 判断基準: React.memo だけでは解決できず、状態更新が頻繁に走るとき

対策: useReducer と useCallback を組み合わせ、状態更新ロジックをメモ化するだけで、ほとんどのケースで十分です。重いフレームワーク(Redux Toolkit 等)を導入する必要はありません。


まとめ

  • 小規模 なら useState が最速
  • 状態が増える、共有が必要になる、非同期が絡む ときは 軽量ストア(useReducer、Zustand、Jotai)へシフト
  • 型安全とパフォーマンスは React のフックだけでも十分 に担保できる

実際に手を動かしてみると、どのタイミングで切り替えるか感覚がつかめます。まずは useReducer を試し、必要に応じて外部ストアを検討してみてください。

詳しい手順はこちら → https://felixstudio0.gumroad.com/?utm_source=qiita&utm_medium=github_actions&utm_campaign=2026-q1&utm_content=qiita-footer

0
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
0
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?