Open2

【React Global State管理】 zustand vs jotai vs valtio

まさぴょんまさぴょん

zustand vs jotai vs valtio

Zustand Doc 内の State管理ツール比較記事

https://zustand.docs.pmnd.rs/getting-started/comparison

npm trendsでの比較

https://npmtrends.com/jotai-vs-valtio-vs-zustand

React アプリケーションでの状態管理に用いられるライブラリとして、jotaivaltiozustandの3つについて整理します。

それぞれの特徴

jotai

概要:
jotai は、状態を「atom」という最小単位で定義し、それをReactコンポーネントから直接参照することで状態を管理するライブラリです。基本的には「1つの状態 = 1つのAtom」という単純なモデルであり、React 公式の useState を拡張したような感覚で使えます。また React の Context の上に構築されているため、比較的自然な使い心地を得られます。

メリット:

  • シンプルな原則: Atom単位で状態を定義し、コンポーネントは必要なAtomだけを読むため、依存関係が明確でわかりやすい。
  • 細粒度な更新: Atom単位で変更がトリガーされるため、不要な再レンダーを抑制しやすい。
  • React Hooksとの親和性: useAtom Hookによりシンプルな読み書きが可能。

デメリット:

  • Atomの管理増加: 状態を細かく分割しすぎるとAtomの数が増え、管理が複雑になる可能性がある。
  • 依存関係管理: Atom間で計算依存などを行う場合、依存関係の扱いがやや複雑になる。

valtio

概要:
valtio は、Proxyオブジェクトを用いて状態をトラッキングする仕組みを持ったステート管理ライブラリです。状態は基本的にプレーンな JavaScript オブジェクトで、proxy を生成し、それを更新すると自動的にコンポーネントが再レンダーされます。つまり、従来のオブジェクト操作そのままの直感的な書き方ができる点が強みです。

メリット:

  • 直感的なオブジェクト操作: 状態をJSのオブジェクトとして扱い、直接更新するだけで反映されるため、学習コストが低い。
  • シンプルな導入: useSnapshot で状態を読み取るシンプルなAPI。

デメリット:

  • 大規模アプリでの構造化が課題: 状態が単一のオブジェクトツリーでまとまっていくため、増大すると見通しが悪くなる可能性がある。
  • 再レンダー制御の理解: Proxy ベースの更新はブラックボックス的な挙動を感じる場合があり、細かなパフォーマンスチューニングが難しい場合がある。

zustand

概要:
zustand は、Fluxパターンに近いが極めて軽量で、グローバルなストアをHooks経由で扱えるステート管理ライブラリです。createでストアを定義し、そのストアをuseStoreから呼び出します。状態はオブジェクトで管理しますが、selectorを用いることで必要な部分のみレンダーをトリガーできます。

メリット:

  • 軽量・シンプル: Boilerplateが少なく、シンプルなAPIで使い始めやすい。
  • セレクタによる再レンダー制御: useStore にselectorを渡すことで再レンダー範囲を限定しやすい。
  • グローバルストアの定義が簡単: 頻繁に使う共通状態の管理に向いている。

デメリット:

  • ストア構造の分割がやや手動: 大規模化すると複数ストア分割が必要になるが、その分割管理は開発者が行う必要がある。
  • 複雑な依存関係を扱うための仕組みは薄い: 基本は1つ(または複数)のストアで状態を保持するため、依存関係が複雑になると管理が難しい。

比較表

項目 jotai valtio zustand
基本概念 Atom(最小の状態単位) Proxyによるオブジェクト状態 グローバルストアとHook
状態定義方法 atom()関数でAtomを定義 proxy()でラップしたJSオブジェクト create()でストア生成
状態更新方法 useAtomでAtomをread/write オブジェクトを直接変更 useStoreでGetter/Setter
再レンダー制御 Atom単位の依存関係で不要な再描画を抑制 Proxyによる自動トラッキング(細かい制御難) Selectorで必要な状態のみ取得
学習コスト 比較的低い(React Hooksライク) 非常に低い(ネイティブなオブジェクト操作感) 比較的低い(Hooks & シンプルなAPI)
大規模開発向き Atom数が増えると管理が煩雑になり得る 状態ツリーが肥大化すると見通しが悪くなる 複数ストア管理が必要、依存関係の管理は開発者次第
エコシステム 新しめ、コミュニティ拡大中 同じく新しめ、周辺ツールは増えつつある 比較的確立、導入事例が多い
パフォーマンス 細粒度制御により最適化可能 Proxyによる直感的反映だが最適化は工夫必要 セレクタによる再レンダー制御で良好なパフォーマンス
メンテナンス性 Atom間の依存管理がカギ 大型化した場合の構造化が課題 ストア分割とセレクタ設計が重要

まとめ

  • jotai: 細かい状態単位(Atom)を定義し、必要な分だけ読み書きするスタイル。小~中規模で細かい状態分割を行いたい場合や、React Hooks的な感覚で管理したい場合に向いている。
  • valtio: proxyによる直感的なオブジェクト操作で、状態管理をシンプルにしたい場合に有効。既存の状態管理ロジックをあまり変えずにReact側から利用したい場合などに良い選択肢。
  • zustand: 軽量で実績が多く、グローバル状態を手軽に管理可能。複雑な依存関係が少なく、単純なストア管理を迅速に行いたい場合に適している。

それぞれの特性を理解した上で、アプリケーションの規模・複雑性・開発スタイルに合わせて選択すると良いでしょう。