JotaiのDevtoolsを試してみよう!
はじめに
こんにちは、エンジニアの籏野です。
突然ですが、皆さんは Web アプリを作る際にどのような方法で状態管理を行っているでしょうか?
私は長く Redux を使っていましたが、よりシンプルに状態管理を行うことができる Jotai というライブラリを最近使い始めました。
Jotai への入門については様々な記事がありますので割愛して、本記事では Jotai の Devtools を使ってみた紹介をします。
試した内容は以下のリポジトリに置いていますので合わせてご確認ください。
Devtools とは
Redux を利用している方ならきっと誰もが利用しているであろう現在の状態や過去の状態との差分をブラウザ上で確認できるあれです。
Jotai にも同様の Devtools があり、開発時にはぜひ入れておきたいですね。
Jotai の Devtools は上記の redux-devtools を利用したものと、Jotai が独自に UI も提供した Devtools の 2 種類があるようですのでそれぞれ試しました。
準備
create-next-app で簡単にアプリを立ち上げます。
追加で必要なライブラリをインストールしましょう。
$ npx create-next-app
$ npm install jotai jotai-devtools @emotion/react
今回は簡単な Counter コンポーネントを用意しましたので、カウントの状態の変化の様子を Devtools で確認します。
Counter コンポーネント
"use client";
import { atom, useAtom, Provider } from "jotai";
const couterAtom = atom(0);
function Counter() {
const [count, setCount] = useAtom(couterAtom);
return (
<div>
<h1>Counter</h1>
<div>
<button
style={{
width: "30px",
height: "30px",
}}
disabled={false}
onClick={() => setCount((c) => c + 1)}
>
+
</button>
<span
style={{
margin: "0 10px",
}}
>
{count}
</span>
<button
style={{
width: "30px",
height: "30px",
}}
onClick={() => setCount((c) => c - 1)}
>
-
</button>
</div>
</div>
);
}
export default function CounterWithDevtools() {
return (
<Provider>
<Counter />
</Provider>
);
}
redux-devtools を利用した Devtools
jotai-devtools の useAtomsDevtools を利用します。
import { useAtomsDevtools } from "jotai-devtools";
function AtomsDevtools(props: { children: React.ReactNode }) {
useAtomsDevtools("demo");
return <>{props.children}</>;
}
export default function CounterWithDevtools() {
return (
<Provider>
<AtomsDevtools>
<Counter />
</AtomsDevtools>
</Provider>
);
}
上記のコンポーネントで確認したいコンポーネントを囲うことで、redux-devtools から状態を確認できます。
Jotai 独自の Devtools
jotai-devtools の Devtools を利用します。
import { Devtools } from "jotai-devtools";
export default function CounterWithDevtools() {
return (
<Provider>
<Devtools />
<Counter />
</Provider>
);
}
上記設定すると、Jotai のアイコンがアプリ上に表示されます。
これをクリックすると、Jotai 独自の Devtools が表示され現在保持している状態を確認できます。
このとき、atom に対して debugLabel を付けておくと Devtools 上で atom の判別がやりやすくなるのでぜひ設定してください。
const counterAtom = atom(0);
counterAtom.debugLabel = "counterAtom";
また過去の状態との差分を見る場合には、「Time travel」タブにて「Record snapshot history」を有効にします。
Tips
Provider と Devtools の適用について
今回の記事では説明のため Counter コンポーネントに直接 Jotai の Provider や Devtools を適用しました。
しかし、実際の開発ではコンポーネント単位でこれらを適用しなければならない場面は少ないと思います。
そのため、Next.js を利用している場合は layout.tsx や_app.tsx にてまとめて適用するのがおすすめです。
App Router を利用している場合、Jotai の Provider はクライアントコンポーネント内で利用する必要がある点も注意してください。
// jotai.tsx
"use client";
import { Provider } from "jotai";
import { DevTools } from "jotai-devtools";
type JotaiProviderProps = {
children: React.ReactNode;
};
export function JotaiProvider(props: JotaiProviderProps) {
return (
<Provider>
<DevTools />
{props.children}
</Provider>
);
}
// layout.tsx
import { JotaiProvider } from "@/providers/jotai";
export default function RootLayout(props: { children: React.ReactNode }) {
return (
<html lang="ja">
<body>
<JotaiProvider>{props.children}</JotaiProvider>
</body>
</html>
);
}
debugLabel のつけ忘れを防ぐ
先の通り Jotai の Devtools を利用する場合は debugLabel を付けるのがおすすめです。
これを開発者に強制もしくはやりやすくさせるために、atom のラッパーを用意するようにしてみました。
地味ではありますが、debugLabel の付け忘れが減ると思います。
import { atom as rawAtom } from "jotai";
export function createAtom<T>(initialValue: T, key: string) {
const atom = rawAtom(initialValue);
atom.debugLabel = key;
return atom;
}
まとめ
jotai-devtools を利用することで Redux での開発に利用していた Devtools をそのまま使えるのはとてもありがたいですね。
独自の Devtools についても開発者コンソールを開くことなく画面の一要素として参照できるのはとても便利に感じました。
皆さんも Devtools を使ってより快適な開発ライフを!
この記事を書いた人
籏野 拓
2018 年新卒入社
今年もフルーツタルトを作りました(既に 2 回)
Discussion