---
title: "MobXとは？Reactの状態管理をシンプルにする仕組みと使い方【v6対応】"
url: "https://www.issoh.co.jp/tech/details/3414/"
published: 2024-08-28
updated: 2026-07-19
categories: ["React"]
publisher: "株式会社一創"
---

# MobXとは？Reactの状態管理をシンプルにする仕組みと使い方【v6対応】

MobXは、状態（データ）の変化を自動で追跡し、その状態を使っている画面だけを再描画するReact向けの状態管理ライブラリです。「状態を変えたらUIが勝手に追従する」という考え方で、Reduxのような定型コードを書かずに状態管理を実装できます。本記事のMobXは、JavaScript／TypeScript向けライブラリ（mobx.js.org）を指します。米国市場に上場するMobix Labs（ティッカー「MOBX」）とは無関係です。ここではMobX 6を前提に、中核となる考え方、Reactとの連携、そしてReduxやZustandとの使い分けまでを実コードで整理します。

## まとめ：MobXの要点

- MobXはObservableにした状態の変化を追跡し、依存するUIだけを自動で再描画するリアクティブな状態管理ライブラリ。
- 中核はObservable（状態）・Action（変更）・Computed（派生値）の3つ。副作用はReaction（autorun／reaction）で扱う。
- MobX 6ではデコレータが既定でなくなり、`makeAutoObservable`でストアを定義するのが標準の書き方。
- Reactとは`mobx-react-lite`の`observer`で連携する。クラスコンポーネントやProvider／injectが必要なときだけ`mobx-react`を使う。
- 記述量は少ないが規模が大きいほど設計規律が要る。厳格な監査可能性ならRedux、最小構成ならZustandと使い分ける。

以降で、それぞれの仕組みと具体的な書き方を順に見ていきます。

## MobXの全体像：リアクティブな状態管理の考え方

MobXは2015年にMichel Weststrate氏が「Mobservable」として公開し、翌年MobXへ改称したライブラリです。設計思想は「派生できるものはすべて自動的に派生させる」というもので、状態を書き換えたら、その状態に依存する計算値や画面が自動的に更新されます。開発者が「どこを再描画するか」を手で指定する必要がありません。

Reduxが「状態は一箇所・変更はアクションとリデューサー経由」という明示的な規約でボイラープレートが増えがちなのに対し、MobXは通常のオブジェクトのプロパティを書き換える感覚でコードを書けます。この差が、MobXが「記述量が少ない」と評価される理由です。半面、どこでも状態を変えられるため、規模が大きくなると変更箇所を追いにくくなる弱点もあります（後述のActionと使い分けで抑えます）。

## MobXの3つの中核概念：Observable・Action・Computed

MobXの仕組みは、状態を表すObservable、状態を変えるAction、状態から値を導くComputedの3つで説明できます。この3つに、状態変化に反応して副作用を起こすReactionを加えた4つがAPIの土台です。

### Observable：追跡対象になる状態

Observableは「変化を監視される状態」です。オブジェクト・配列・Map／Set・プリミティブを対象にできます。あるコンポーネントがObservableのどのプロパティを読んだかをMobXが記録し、そのプロパティが変わったときだけ該当コンポーネントを再描画します。「使っている値だけを追跡する」ため、無関係な再描画が起きにくいのが特徴です。

### Action：状態を変更する窓口

Actionは状態を書き換えるメソッドです。MobXでは変更をActionに集約することが推奨され、MobX 6は既定でstrict mode（`enforceActions: "observed"`）が働きます。リアクションが参照している状態をAction外で書き換えるとエラーになります。変更箇所をActionに限定すると、状態がいつ・どこで変わったかを追いやすくなり、大規模化したときのデバッグ性が上がります。`makeAutoObservable`を使えば、メソッドは自動的にActionとして扱われます。

### Computed：依存から導かれるキャッシュ付きの派生値

Computedは、既存のObservableから計算される値です。ゲッターとして定義し、依存するObservableが変わったときだけ再計算されます。結果はキャッシュされ、誰も参照していない間は計算されないため、同じ導出をUIの複数箇所で使っても無駄な計算が走りません。「合計金額」「未完了件数」のような、状態から一意に決まる値はComputedに寄せるのが定石です。

### Reaction：状態変化に応じた副作用

ComputedがUIに表示する「値」を作るのに対し、Reactionは「副作用」を起こします。`autorun`は依存する状態が変わるたびに関数を再実行し、`reaction`は監視対象と副作用を分けて書けます。ローカルストレージへの保存やログ出力など、画面描画以外の反応に使います。Reactコンポーネントの再描画自体は、後述の`observer`が内部でReactionを張って実現しています。

## MobX 6の書き方：makeAutoObservableとデコレータの位置づけ

ここが古い解説記事と最も差が出るところです。MobX 4／5時代はデコレータ（`@observable`／`@action`）が事実上の標準でしたが、MobX 6ではデコレータが既定ではなくなり、コンストラクタで`makeObservable`／`makeAutoObservable`を呼ぶ方式が標準になりました。ビルド設定なしでどの環境でも動く形に統一するための変更です。

### makeAutoObservableでストアを定義する（推奨）

`makeAutoObservable`は、プロパティを自動でObservable、ゲッターをComputed、メソッドをActionとして推論します。注釈を1つずつ書かずに済むため、公式ドキュメントでもまずこの書き方が示されています。

```
import { makeAutoObservable } from "mobx"

class CounterStore {
  count = 0

  constructor() {
    makeAutoObservable(this)
  }

  increment() {
    this.count++
  }

  get isEven() {
    return this.count % 2 === 0
  }
}

export const counterStore = new CounterStore()
```

この例では`count`がObservable、`increment`がAction、`isEven`がComputedに自動で振り分けられます。旧記事にあった`observable({ count: 0, increment() {...} })`というオブジェクト直書きも動きますが、クラス＋`makeAutoObservable`のほうがTypeScriptとの相性がよく、現在の主流です。

### makeObservableで注釈を明示する場合

自動推論を効かせたくない、あるいは一部だけ扱いを変えたいときは`makeObservable`で明示します。第2引数で`observable`／`action`／`computed`を指定します。継承したクラスやgetterの扱いを細かく制御したい場面で使い分けます。

### デコレータを使う場合の注意

デコレータ構文自体はMobX 6でも「modern decorators（`@observable accessor`）」として利用できますが、既定ではありません。既存のMobX 4／5プロジェクトからの移行では、デコレータを外して`makeObservable(this, {...})`に置き換えるのが公式の移行手順です。新規開発でわざわざデコレータ設定を足す必要は基本的にありません。

## MobXとReactの連携：mobx-react-liteとmobx-reactの選び方

MobX本体はReactに依存しません。Reactとつなぐにはバインディングパッケージを入れ、コンポーネントを`observer`でラップします。ここで`mobx-react-lite`と`mobx-react`のどちらを選ぶかが最初の分岐点です。

### インストールとセットアップ

関数コンポーネント中心の現在の開発では、本体と軽量バインディングを入れます。

```
npm install mobx mobx-react-lite
```

本記事執筆時点の最新は mobx 6.16／mobx-react-lite 4.1 系です（パッチは更新が速いため、最新は公式・npmで確認してください）。クラスコンポーネントやProvider／injectも使いたい場合は、`mobx-react-lite`の代わりに`mobx-react`（9系）を入れます。

### observerでコンポーネントをリアクティブにする

`observer`でラップしたコンポーネントは、レンダリング中に読んだObservableを自動で追跡し、その値が変わったときだけ再描画されます。

```
import { observer } from "mobx-react-lite"
import { counterStore } from "../stores/counterStore"

const Counter = observer(() => (
  <div>
    <p>{counterStore.count}（{counterStore.isEven ? "偶数" : "奇数"}）</p>
    <button onClick={() => counterStore.increment()}>+1</button>
  </div>
))

export default Counter
```

`useState`を使わずとも、ストアの`count`を書き換えるだけで表示が更新されます。ストアはコンポーネント外に置くか、React Contextで配布します。

### mobx-react-liteとmobx-reactの使い分け

両者の違いを整理すると、選択基準は明確です。

| 項目              | mobx-react-lite   | mobx-react     |
| --------------- | ----------------- | -------------- |
| 対応コンポーネント       | 関数のみ              | 関数＋クラス         |
| Provider／inject | なし（useContextで代替） | あり             |
| サイズ             | 約1.5kB（gzip）と軽量   | lite＋クラス対応分    |
| 推奨用途            | 新規・関数コンポーネント中心    | クラスや旧来APIが残る場合 |

結論として、新規のReactプロジェクトなら`mobx-react-lite`で十分です。`mobx-react`は内部で`mobx-react-lite`を使っており、クラスコンポーネントやProvider／injectという追加機能が要るときだけ選べばよい、という関係になっています。

## 実装例：Computedとリストを扱うTodoストア

カウンターより実務に近い例として、Todoリストを見ます。追加・完了トグルをActionに、未完了件数をComputedに寄せるのが典型的な設計です。

```
import { makeAutoObservable } from "mobx"

class TodoStore {
  todos = []

  constructor() {
    makeAutoObservable(this)
  }

  addTodo(title) {
    this.todos.push({ title, done: false })
  }

  toggle(index) {
    this.todos[index].done = !this.todos[index].done
  }

  get remaining() {
    return this.todos.filter((t) => !t.done).length
  }
}

export const todoStore = new TodoStore()
```

`remaining`はComputedなので、`todos`の中身が変わったときだけ再計算されます。この値を`observer`付きコンポーネントで表示すれば、未完了件数のバッジは常に最新に保たれ、件数を手で数え直すコードは不要です。状態（`todos`）・変更（`addTodo`／`toggle`）・派生（`remaining`）が3つの役割に分かれている点が、MobXらしい状態設計です。

## MobX・Redux・Zustandの比較：どれを選ぶか

Reactの状態管理は選択肢が多く、MobXが常に最適とは限りません。代表的な3つを比べます。

| 観点    | MobX       | Redux（RTK） | Zustand |
| ----- | ---------- | ---------- | ------- |
| パラダイム | 可変・リアクティブ  | 不変・単方向     | 可変・フック  |
| 記述量   | 少ない        | 多め（RTKで軽減） | 最小      |
| 変更追跡  | Action推奨   | アクション必須で明確 | set関数   |
| 向く規模  | 中〜大（要設計規律） | 大・複数人      | 小〜中     |

使い分けの指針ははっきりしています。状態の変更履歴を厳密に追える単方向フローや、大人数での一貫性が最優先ならReduxが向きます。逆に、ストアを1ファイルで最小構成に収めたいならZustandが軽快です。MobXは「オブジェクトを直接書き換える手軽さ」と「自動追跡による最適な再描画」を両立したい中規模開発に合います。

一方で、MobXを避けたほうがよい場面もあります。状態変更の監査可能性を最重視するチーム、あるいは「どこで状態が変わったか」を厳密なルールで縛りたいプロジェクトでは、どこでも書き換えられるMobXの自由度がかえってリスクになります。その場合はActionへの集約とstrict modeを徹底するか、Reduxを選ぶべきです。各ライブラリの詳細は[Reduxの基本的な使い方](/tech/details/3060/)と[Zustandの使い方](/tech/details/7615/)も併せて確認してください。

## よくある質問（FAQ）

### MobXとは何ですか？株のMOBXとは違いますか？

本記事のMobXは、JavaScript／TypeScript向けの状態管理ライブラリ（mobx.js.org）です。検索結果には米国上場企業Mobix Labs（ティッカー「MOBX」）の株価情報も混在しますが、両者は無関係です。プログラミングで使うのはこのライブラリのほうです。

### mobx-reactとmobx-react-liteの違いは？

`mobx-react-lite`は関数コンポーネント専用の軽量版（約1.5kB前後・gzip）で、Provider／injectを持ちません。`mobx-react`はそれに加えてクラスコンポーネント対応とProvider／injectを備えます。関数コンポーネント中心の新規開発なら`mobx-react-lite`で十分です。

### MobXのインストール方法は？

npmなら`npm install mobx mobx-react-lite`、yarnなら`yarn add mobx mobx-react-lite`です。本体の`mobx`とReactバインディングを分けて入れます。クラス対応が必要なら`mobx-react-lite`を`mobx-react`に置き換えます。

### MobXとReduxはどちらを使うべきですか？

変更履歴の厳密な追跡や大人数での一貫性を優先するならRedux（Redux Toolkit）、記述量を抑えて手軽に書きたい中規模開発ならMobXが向きます。プロジェクトの規模とチームの運用ルールで選び分けるのが実務的です。

### MobXは今も使われていますか？メンテナンスされていますか？

はい。MobXはメジャーバージョン6として継続的に更新されており（本記事時点で6.16系）、React以外のフレームワークでも利用されています。デコレータ非依存の書き方に統一された現行版は、ビルド設定を選ばず導入しやすくなっています。

## 関連記事

- [Reduxの基本的な使い方：ステート管理の基礎](/tech/details/3060/)
- [Zustandとは？Reactの状態管理を最小コードで実現する使い方を徹底解説【v5対応】](/tech/details/7615/)
- [Reactフックの基本と導入：React 16.8で追加された新機能の概要](/tech/details/3671/)

---

出典: [MobXとは？Reactの状態管理をシンプルにする仕組みと使い方【v6対応】](<https://www.issoh.co.jp/tech/details/3414/>)（株式会社一創）
