Jotai: 状態?! 日本語っぽい名称のReact用ステート管理ライブラリ

## はじめに

本記事では[Jotai](https://github.com/pmndrs/jotai)というReactのライブラリを紹介します。名称は日本語の「状態」から来ています。最近、[Zustand](https://github.com/pmndrs/zustand)というライブラリのメンテナスを任されているのですが([紹介記事](https://qiita.com/daishi/items/deb20d951f532b86f029))、その議論の中でZustandの枠には収まらないアイデアが出てきて、じゃあもう一つ作ればいいじゃん、となりました。Zustandはドイツ語の「状態」なのですが、誰かが日本語の「状態」を調べて、Jotaiって言うんだ、npmでもまだ使われていないパッケージ名だ、となりました。

そんなこんなで9月にリリースしました。リリース時のツイートがこちら

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">we are releasing JŌTAI today <a href="https://t.co/T66zQVyKcz">https://t.co/T66zQVyKcz</a> 🎉 this is <a href="https://twitter.com/dai_shi?ref_src=twsrc%5Etfw">@dai_shi</a> &#39;s take of the atomic state model. quite similar to recoil but focusses on a small api surface w/ simpler albeit equally powerful atoms and derived state. jōtai is 100% ready for concurrent mode and suspense <a href="https://t.co/5UHTnyBLdh">pic.twitter.com/5UHTnyBLdh</a></p>&mdash; Paul Henschel (@0xca0a) <a href="https://twitter.com/0xca0a/status/1303354125246255104?ref_src=twsrc%5Etfw">September 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## Jotaiとは

Reactのステート管理のライブラリです。一言で言うと、[Recoil](https://recoiljs.org)に近いです。人によってはほぼ同じと言う感想を持つ人もいますし、人によってはRecoilのAPIは複雑すぎるけどJotaiのAPIはシンプルで違うと言う感想を持つ人もいます。JotaiはRecoilにインスパイアされて作られていますし、あえて似せている部分もあります。しかし、背景は少し違います。JotaiはContext APIのパフォーマンス問題を解決することが目的で、その際のAPIとしてatomが都合良かったということです。atomモデルのAPIを実現するだけであれば、ZustandのようにContext APIではなくReactの外にstoreを作る方が筋がいいかもしれません。

## JotaiのAPI

JotaiのAPIはuseStateやuseContextに似ています。Jotaiが提供するAPIは `Provider`, `atom`, `useAtom` の3つです。ProviderはContext Providerのように使いますが、全atomで共通でありpropsを受け取りません。atomはatom(の設定オブジェクト)を生成します。useAtomはuseContextのように使いますが、contextの代わりにatomを指定します。

```jsx
import { Provider, atom, useAtom } from 'jotai';

const textAtom = atom('hello');

const Component = () => {
  const [text, setText] = useAtom(textAtom);
  return (
    <input value={text} onChange={e => setText(e.target.value)} />
  );
};

const App = () => (
  <Provider>
    <Component />
  </Provider>
);
```

`textAtom`は他のコンポーネントでも使うことができます。その際はuseStateとは異なり値はProvider内で共有されます。

useStateからuseAtomに変更する例はこちら

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">How to use Jotai <a href="https://t.co/OJjJMx6v6k">https://t.co/OJjJMx6v6k</a> in the simplest way.<br><br>From React useState to Jotai useAtom: Counter example. <a href="https://t.co/RMhyVlyJMu">pic.twitter.com/RMhyVlyJMu</a></p>&mdash; Daishi Kato (@dai_shi) <a href="https://twitter.com/dai_shi/status/1305516005418958848?ref_src=twsrc%5Etfw">September 14, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 派生atom

上記の利用方法だけでも一定の有用性はありますが、atomの有用性は派生atomにもあります。派生atomは、すでに定義されている一つまたは複数のatomから、新しいatomとして定義するものです。例えば、先ほどの`textAtom`から次のような派生atomを作ることができます。

```js
const uppercaseAtom = atom(get => get(textAtom).toUpperCase());
```

uppercaseAtomはtextAtomが変化した際にのみ再評価されるため、それをuseAtomで利用するコンポーネントの再レンダリングが最小限に抑えられます。

## リポジトリ

GitHubのページはこちらです。

<https://github.com/pmndrs/jotai>

基本的な使い方はREADMEにコンパクトに書かれていますのでぜひご参照ください。

## 紹介YouTube

YouTubeに紹介動画を上げてくれた方がいるので、合わせてご覧ください。

- [Jotai Tutorial - Better than Recoil?](https://youtu.be/TlP2XB6TFVw)
- [Introducing Jotai || React State Manager Tutorial](https://youtu.be/x9usS4l1VD0)
- [Comparing Recoil and Jotai: React State](https://youtu.be/QQ1jh6psRa4)

## おわりに

本記事では、あまり詳細な使い方に踏み込まず表面的な紹介をしました。興味がある方はまずこの基本的な使い方から試してみてください。より詳細なトピックとしては、atomの書き込みのカスタマイズ(writable atom)、非同期処理(suspense)やConcurrent Mode対応などがあります。少し触って慣れてきた後に試してみるのが良いでしょう。

質問などありましたら、お気軽に〜。