Paul Henschel氏は先頃、Reactの新しい状態管理ライブラリであるJōtaiをリリースした。Jōtaiは、最小限のAPI (3つの関数) 、TypeScript対応、およびReact SuspenseとConcurrent Modeとの互換性を主張している。
他の状態に依存しない状態の部分は、Jōtaiのatom
ファクトリ関数に初期値を渡すことで作成できる。これらの独立した状態の部分は、同じファクトリ関数を使用して派生状態の部分に構成できる。今回、依存関係から派生アトムを計算する関数を渡す:
const count1 = atom(1)
const count2 = atom(2)
const count3 = atom(3)
const sum = atom(get => get(count1) + get(count2) + get(count3))
atom
ファクトリ関数を使用して、インプレースリデューサ (in-place reducers) 、つまり、引数パラメータから状態の一部を更新する関数を定義できる:
const decrementCountAtom = atom(
get => get(countAtom),
(get, set, _arg) => set(countAtom, get(countAtom) - 1),
)
function Counter() {
const [count, decrement] = useAtom(decrementCountAtom)
return (
<h1>
{count}
<button onClick={decrement}>Decrease</button>
)
}
atom
ファクトリ関数を使用すると、開発者はアクション、つまりエフェクトを実行する可能性のあるプロシージャを定義し、関連する状態を更新できる。アクションは非同期の場合がある:
const fetchCountAtom = atom(
get => get(countAtom),
async (_get, set, url) => {
const response = await fetch(url)
set(countAtom, (await response.json()).count)
}
)
function Controls() {
const [count, compute] = useAtom(fetchCountAtom)
return <button onClick={() => compute("http://count.host.com")}>compute</button>
前のコードは、ReactコンポーネントコンテキストでJōtaiによって処理される状態の一部を操作するために使用されるuseAtom
フックを示している。Reactアプリケーションは、atom
およびuseAtom
APIを使用するためにJōtaiのProvider
コンポーネント内にラップする必要がある。
import { Provider } from 'jotai'
const Root = () => (
<Provider>
<App />
</Provider>
)
前述の3つのAPIを使用して、Jōtaiは余分な再レンダリングを防止する一方で、React SuspenseおよびConcurrent Modeと完全に互換性があると主張している。Daishi Kato氏はさらに説明した:
Jotaiの状態はReactコンポーネントツリー内にあります。[…] Jotaiは、useState+useContextの代替として見ることができます。複数のコンテキストを作成する代わりに、atomは1つの大きなコンテキストを共有します。
Jōtaiは、Recoilと同様の状態管理メカニズムを提供する。表面上の3つの関数のAPIと1.3KBとコードバンドルが小さく、対する、Recoilのフル機能のAPIは9KBある。
RecoilとJōtaiはどちらも、すべての共有コンポーネントのクロージャで使用可能なatomを作成することにより、コンポーネント間で状態の一部を共有する。標準的な代替策は、状態の一部をコンポーネントツリーの共通の祖先まで持ち上げて、それらの状態の部分に依存コンポーネントがアクセスできるようにすることである。Recoilのチームは、後者のアプローチの問題を次のようにまとめた:
互換性とシンプルさの理由から、外部のグローバルな状態ではなく、Reactの組み込みの状態管理機能を使用するのが最善です。しかし、Reactには一定の制限があります:
- コンポーネントの状態は、共通の祖先にプッシュすることによってのみ共有できますが、これには、再レンダリングする必要がある巨大なツリーが含まれる場合があります。
- コンテキストは単一の値のみを保存でき、それぞれが独自のコンシューマを持つ値の無期限のセットではありません。
- これらはどちらも、ツリーのリーフ (状態が使用される場所) からツリーの上部 (状態が存在する場所) をコード分割することを困難にします。
JōtaiはMITライセンスに基づくオープンソースライブラリである。