
Reactの状態管理ライブラリといえばReduxが有名ですが、学習コストの高さから初心者には難しいと感じられることがあります。そこでおすすめなのがJotaiです。
Jotai は、初心者にも扱いやすく、Reactの基本を理解していればすぐに使い始められます。Jotaiを習得することで、複数のコンポーネント間で状態を共有する実践的なスキルが身につき、より規模の大きなアプリ開発に対応できるようになります。
この記事で学べること:
- Jotaiの基本的な仕組みと特徴
- atom と useAtom を使った状態管理の実装方法
- Provider と Store による高度な状態管理
- Todoアプリを通じた実践的な開発手法
この記事を読み終える頃には、Jotaiを使った状態管理の基本が理解でき、実際のアプリに導入できるようになります。それでは、一緒に学んでいきましょう。
Jotaiとは
Jotaiとは、Reactで使える状態管理ライブラリです。Reactの状態を useState のようにシンプルに扱えるため、状態管理ライブラリが初めての方にも使いやすいのが特徴です。
Jotaiはアプリ内のデータ(状態)を「atom(アトム)」という小さな単位で管理し、不要な再レンダリングを防ぎます。
状態管理ライブラリとは
状態管理ライブラリとは、アプリ内で使われる「データ(状態)」を効率的かつ一元的に管理するためのツールです。
状態(state)とは
状態(state)とは、アプリ上でユーザが操作した内容が「今どういう状況にあるか」を示すデータのことです。
- ユーザーのログイン状態
- ショッピングカートに入っている商品
- フォームに入力されたテキスト
これらはユーザーがアプリを使う中で頻繁に変化します。状態を適切に管理することで、アプリの動作がスムーズになり、ユーザー体験の向上につながります。
状態管理ライブラリはなぜ必要か?
状態管理ライブラリが必要な理由は、アプリが大規模になるにつれて、Reactの useState や useReducer などのHooksだけでは状態管理が難しくなるためです。
-
状態の複雑化
アプリが扱う状態が増えると、どの状態がどこで管理されているのかが分かりにくくなり、開発や保守が困難になります。
-
状態の共有の複雑さ
親コンポーネントから子コンポーネントへ状態を渡す際、いわゆる「バケツリレー」のようなコードが増え、全体の可読性が低下します。
-
パフォーマンスの問題
状態の変更による不要な再レンダリングが発生し、アプリの動作が遅くなる場合があります。
多くの開発現場では、こうした課題を解決するために状態管理ライブラリが導入されています。
状態管理を支える4つの仕組み
Jotaiには、状態管理を支える4つの仕組みがあります。
- atom
- useAtom
- Provider
- Store
atom
atom とは、Jotaiで状態を管理するための基本単位です。Reactの useState における状態変数に近い役割を果たします。atom() 関数を使って作成し、初期値を渡します。
import { atom } from 'jotai';
// 初期値が0のatomを作成
const countAtom = atom(0);
// 初期値が空の文字列のatomを作成
const textAtom = atom('');
// オブジェクトを初期値に持つatomを作成
const userAtom = atom({ name: 'Alice', age: 25 });
useAtom
useAtom とは、作成した atom をコンポーネント内で利用するためのフックです。このフックを使うことで、状態の読み取りや更新が簡単に行えます。Reactの useState と似た使用感で状態を扱えます。
import { atom, useAtom } from 'jotai';
// 初期値が0のatomを作成
const countAtom = atom(0);
// 作成したatomの状態をuseAtomで使用する
const [count, setCount] = useAtom(countAtom);
Provider
Provider とは、特定の範囲内で atom の状態を独立させるための仕組みです。通常、Jotai はアプリ全体で状態を共有しますが、Provider を使うことで「この範囲だけで別の状態を持つ」ことができます。
たとえば、同じフォームコンポーネントを複数の場所で使う場合、それぞれ独立した入力状態を管理したいときに便利です。
import { Provider } from 'jotai';
const App = () => (
// Providerで囲んだ範囲内でatomの状態を独立させる
<Provider>
<Child />
</Provider>
);
Provider は次に紹介する Store と組み合わせて使用します。
Store
Store とは、atom の状態を実際に保存する場所のことです。Jotai はデフォルトで1つの Store をアプリ全体に用意しているため、通常は意識する必要がありません。カスタム Store が必要になるのは、Provider で範囲を分けた際に、その範囲ごとに異なる状態を持たせたいときです。
import { Provider, createStore } from 'jotai';
// Storeを作成
const myStore = createStore();
const App = () => (
// ProviderにStoreを指定し、この範囲でmyStoreの状態を使用
<Provider store={myStore}>
<Child />
</Provider>
);
Provider に作成した Store を渡すことで、その範囲内では指定した Store の状態が使われます。
ProviderとStoreを組み合わせた使い方
Provider と Store を組み合わせることで、同じ atom でも場所によって異なる状態を持たせられます。
- Provider:「ここからここまで」という範囲を定義
- Store:その範囲で使う状態の保管場所を用意
- Provider に Store を指定することで、範囲ごとに状態を分離
import { atom, Provider, createStore } from 'jotai';
const store1 = createStore();
const store2 = createStore();
// countAtomを定義
const countAtom = atom(0);
function App() {
return (
<div>
<Provider store={store1}>
{/* ここでのcountAtomの値はstore1で管理 */}
<Counter />
</Provider>
<Provider store={store2}>
{/* ここでのcountAtomの値はstore2で管理 */}
{/* store1の値とは独立している */}
<Counter />
</Provider>
</div>
);
}
この例では、同じ countAtom でも store1 の範囲と store2 の範囲で別々のカウント状態を持ちます。モーダルやタブなど、同じコンポーネントを複数使う場合に状態を分離できます。
ここまでJotaiの基本的な仕組みを学びました。次のセクションでは、実際にJotaiをインストールし、ハンズオンを通して理解を深めていきましょう。
Jotaiのインストール方法
Reactプロジェクトを作成した後、以下のコマンドを実行すればJotaiをインストールできます。
-
npmでJotaiをインストール
npm install jotai -
yarnでJotaiをインストール
yarn add jotai
Jotaiを使ったハンズオンで理解を深める
このセクションでは、Jotaiを使用したTodoアプリをハンズオン形式で作成します。
Todoアプリの完成イメージ

Todoアプリ作成で学ぶこと
今回のハンズオンでは、Jotaiを使った以下の実装方法を学べます。
- atom を使った状態管理の基本
- 複数のコンポーネント間での状態共有
- 状態の読み取りと更新の実践
ファイル構成
以下の4つのファイルを使用してアプリを構築します。
-
App.jsx
アプリのメインコンポーネント
-
atoms.js
グローバル状態(atom)を定義するファイル
-
AddTask.jsx
新しいタスクを追加するコンポーネント
-
TaskList.jsx
タスクを一覧表示するコンポーネント
1. プロジェクトの準備
React プロジェクトを作成し、Jotai をインストールします。
# プロジェクト作成(Vite使用の場合)
npm create vite@latest jotai-todo -- --template react
cd jotai-todo
# Jotaiのインストール
npm install jotai
2.Todoアプリのコード実装
それぞれのファイルを編集します。
-
App.jsx
// App.jsx import React from 'react'; import AddTask from './AddTask'; import TaskList from './TaskList'; const App = () => { return ( <div> <h1>ToDo Lists</h1> <AddTask /> <TaskList /> </div> ); }; export default App; -
atoms.js
// atoms.js import { atom } from 'jotai'; // タスクのリストを管理するグローバルな状態 // Jotaiのatomを使用して、タスクの配列をアプリ全体で共有 export const taskListAtom = atom([]); -
AddTask.jsx
// AddTask.jsx import React, { useState } from 'react'; import { useSetAtom } from 'jotai'; import { taskListAtom } from './atoms'; const AddTask = () => { const [task, setTask] = useState(''); // JotaiのuseSetAtomで、taskListAtomの状態を更新する関数を取得 const addTask = useSetAtom(taskListAtom); const handleAddTask = () => { if (task.trim()) { // 新しいタスクを追加し、Jotaiのatomに保存 addTask((prevTasks) => [...prevTasks, { id: Date.now(), text: task, completed: false }]); setTask(''); // 入力フィールドをリセット } }; return ( <div> <input type="text" value={task} onChange={(e) => setTask(e.target.value)} placeholder="タスクを入力してください" /> <button onClick={handleAddTask}>Add</button> </div> ); }; export default AddTask; -
TaskList.jsx
// TaskList.jsx import React from 'react'; import { useAtom } from 'jotai'; import { taskListAtom } from './atoms'; const TaskList = () => { // useAtomでtaskListAtomを参照し、現在のタスク一覧と更新関数を取得 const [tasks, setTasks] = useAtom(taskListAtom); const toggleTask = (id) => { // タスクの完了状態を切り替え setTasks((prevTasks) => prevTasks.map((task) => task.id === id ? { ...task, completed: !task.completed } : task ) ); }; return ( <ul> {tasks.map((task) => ( <li key={task.id} // 完了状態に応じて表示を切り替え style={{ textDecoration: task.completed ? 'line-through' : 'none', cursor: 'pointer', }} onClick={() => toggleTask(task.id)} // タスクの完了切り替え > {task.text} </li> ))} </ul> ); }; export default TaskList;
全てのファイルを編集後、次のようなTodoアプリが作成します。

※イメージ図は別にCSSを適用しています。
まとめ
この記事では、Reactの状態管理ライブラリJotaiについて、基本から実践的な使い方まで解説しました。
学んだ内容:
この記事の要点は以下の通りです。
- Jotaiの特徴と状態管理ライブラリが必要な理由
- atom による状態の定義方法
- useAtom による状態の読み取りと更新
- Provider と Store を使った状態の分離管理
- Todoアプリを通じた実践的な実装方法
Jotai は、useState のようにシンプルな記述で状態管理ができるため、初めて状態管理ライブラリを使う方にも適しています。この記事で学んだ知識をもとに、ぜひ実際に手を動かしてアプリ開発に挑戦してみてください。
参考資料
以下のリンクは、この記事で解説した手順や概念に関連する参考資料です。より詳しく学びたい方は、ぜひご覧ください。
-
Jotai公式
-
Jotai Friends
-
Daishi Kato's blog - Thoughts on State Management Libraries in the React Compiler Era
https://blog.axlight.com/posts/thoughts-on-state-management-libraries-in-the-react-compiler-era/
【番外編】USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

プログラミング塾に半年通えば、一人前になれると思っているあなた。それ、勘違いですよ。「なぜ間違いなの?」「正しい勉強法とは何なの?」ITを学び始める全ての人に知って欲しい。そう思って書きました。是非読んでみてください。
「フリーランスエンジニア」
近年やっと世間に浸透した言葉だ。ひと昔まえ、終身雇用は当たり前で、大企業に就職することは一種のステータスだった。しかし、そんな時代も終わり「優秀な人材は転職する」ことが当たり前の時代となる。フリーランスエンジニアに高価値が付く現在、ネットを見ると「未経験でも年収400万以上」などと書いてある。これに釣られて、多くの人がフリーランスになろうとITの世界に入ってきている。私もその中の1人だ。数年前、USBも知らない状態からITの世界に没入し、そこから約2年間、毎日勉学を行なった。他人の何十倍も努力した。そして、企業研修やIT塾で数多くの受講生の指導経験も得た。そこで私は、伸びるエンジニアとそうでないエンジニアをたくさん見てきた。そして、稼げるエンジニア、稼げないエンジニアを見てきた。
「成功する人とそうでない人の違いは何か?」
私が出した答えは、「量産型エンジニアか否か」である。今のエンジニア市場には、量産型エンジニアが溢れている!!ここでの量産型エンジニアの定義は以下の通りである。
比較的簡単に学習可能なWebフレームワーク(WordPress, Rails)やPython等の知識はあるが、ITの基本概念を理解していないため、単調な作業しかこなすことができないエンジニアのこと。
多くの人がフリーランスエンジニアを目指す時代に中途半端な知識や技術力でこの世界に飛び込むと返って過酷な労働条件で働くことになる。そこで、エンジニアを目指すあなたがどう学習していくべきかを私の経験を交えて書こうと思った。続きはこちらから、、、、
エンベーダー編集部
エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。

関連記事

2024.08.24
Reactの基本、useContextを理解しよう
今回は、コンポーネント間でデータを共有するのに役立つuseContextについて解説します。
- React
- フロントエンド

2024.10.28
Reactの基本、useCallbackを理解しよう
useCallbackは、関数をメモ化し、再レンダリング時に不必要な関数の再作成を避けることができる仕組みです。
- React
- フロントエンド

2024.07.15
Reactの基本、propsを理解する
フロントエンドエンジニアになりたい、初めてReactを学ぶ方に向けて、この記事ではReactの基本であるpropsについて解説します。propsはReactアプリケーションを構成する上で、必須の知識です。propsの基本を押さえておくことで、これからのReact学習の理解度が深まります。基本を学び、フロントエンドエンジニアへの道を進んでいきましょう!
- React
- フロントエンド

2024.10.22
Reactの基本、useMemoを理解しよう
この記事では、useMemoに焦点を当て、詳しく解説します。useMemoは、関数の結果をメモ化し、再レンダリング時に不必要な再計算を避けることができる仕組みです。それでは、一緒に学んでいきましょう。
- React
- フロントエンド


