状態管理

JotaiTodoアプリ

実践的な Todo アプリで学ぶ Jotai の応用パターン

この Todo アプリで学べること
Jotai の応用パターンを実践的に学びます

💾 atomWithStorage

localStorage に状態を永続化

📖 読み取り専用 Atom

フィルタリング、統計情報の計算

✏️ アクション Atom

追加・切替・削除の書き込み操作

🔄 useState + Jotai

ローカルとグローバルの使い分け

Todo アプリ
ブラウザを閉じても保存される Todo アプリ
進捗0/0 完了(0%)

Todo がありません

atomWithStorage
localStorage に自動保存する Atom

jotai/utilsに含まれるユーティリティです。 ブラウザをリロードしても状態が保持されます。

import { atomWithStorage } from "jotai/utils";

// 第1引数: localStorage のキー名
// 第2引数: 初期値
const todosAtom = atomWithStorage(
"jotai-todos",
[]
);
アクション Atom パターン
CRUD 操作を Atom として定義する

書き込み専用の派生 Atom を「アクション」として使うと、 ロジックを Atom 層に移動でき、コンポーネントがシンプルになります。

// 追加アクション
const addTodoAtom = atom(
null,
(_get, set, text: string) => {
const newTodo = {
id: crypto.randomUUID(),
text, completed: false
};
set(todosAtom, (prev) =>
[...prev, newTodo]
);
}
);
useState と Jotai の使い分け
ローカルとグローバルの適切な使い分け

useState を使う場面

  • • 入力フォームの一時的な値
  • • モーダルの開閉状態
  • • ドロップダウンの展開状態
  • • そのコンポーネントでしか使わない状態

Jotai を使う場面

  • • 複数コンポーネントで共有する状態
  • • 永続化が必要な状態(atomWithStorage)
  • • 派生値の計算が必要な状態
  • • アプリ全体のテーマや設定

この Todo アプリでの使い分け

// ローカル: 入力中のテキスト(このコンポーネントだけ)
const [text, setText] = useState("");

// グローバル: Todo リスト(複数コンポーネントで共有)
const addTodo = useSetAtom(addTodoAtom);
Atom の設計パターン
この Todo アプリの Atom 構成図
┌─────────────────────────────────────────────┐
│              Primitive Atoms                │
│                                             │
│  todosAtom ─────── atomWithStorage          │
│  (Todo[])          (localStorage に保存)      │
│                                             │
│  filterAtom ────── atom("all")              │
│  ("all"|"active"|"completed")               │
├─────────────────────────────────────────────┤
│           Derived Atoms (読み取り専用)          │
│                                             │
│  filteredTodosAtom  ← todosAtom + filterAtom │
│  todoStatsAtom      ← todosAtom             │
├─────────────────────────────────────────────┤
│           Action Atoms (書き込み専用)          │
│                                             │
│  addTodoAtom        → todosAtom             │
│  toggleTodoAtom     → todosAtom             │
│  removeTodoAtom     → todosAtom             │
│  clearCompletedAtom → todosAtom             │
└─────────────────────────────────────────────┘
おめでとうございます!🎉
Jotai の基礎から応用まで学びました

ここまでで、Jotai の主要なパターンをすべて学びました。

  • Primitive Atom と useAtom の基本
  • useAtomValue / useSetAtom による最適化
  • 読み取り専用・書き込み専用・読み書き可能な派生Atom
  • atomWithStorage による永続化
  • アクション Atom パターン
  • useState と Jotai の使い分け