jotaiとは??
ライブラリからも推測できる通り、日本発のReactの状態管理ライブラリです。Recoil等と比較し、軽量でサクサクかける事が好まれているようです。
公式のDemoが2つ用意されていたため、実際に実装してみます。
Demo1(文字数の取得、大文字変換処理)
CodeSandBoxで公開されているので、リンクを貼っておきますのでみてみてください。ここでは画像とソースコードを貼っておきます。
■概要
TextAreaに入力した値の文字数と大文字変換する処理。
App.tsx
import React from "react";
import { Provider, atom, useAtom } from "jotai";
const textAtom = atom("hello");
// get(textAtom)で文字列を取得可能
const textLenAtom = atom((get) => get(textAtom).length);
const uppercaseAtom = atom((get) => get(textAtom).toUpperCase());
const Input = () => {
const [text, setText] = useAtom(textAtom);
return <input value={text} onChange={(e) => setText(e.target.value)} />;
};
const CharCount = () => {
// textAtomから派生したtextLenAtomを利用
const len = useAtom(textLenAtom);
return <div>Length: {len}</div>;
};
const Uppercase = () => {
// textAtomから派生したuppercaseAtomを利用
const [uppercase] = useAtom(uppercaseAtom);
return <div>Uppercase: {uppercase}</div>;
};
const App = () => (
<Provider>
<Input />
<CharCount />
<Uppercase />
</Provider>
);
export default App;
→確かにサクサクかけていいですね。キー値を設定しなくてよい、また簡単にコピーができる所がいい所ですね。
Demo2(API通信で取得した値をコンポーネントに反映する)
概要:APIで取得したレスポンスをコンポーネントに反映し表示するプログラムです。右下の→を押すと、次の記事が表示される仕様です。
App.tsx
import React, { Suspense } from "react";
import { Provider, atom, useAtom } from "jotai";
import { a, useSpring } from "@react-spring/web";
// IDを設定
const postId = atom(9001);
// atomの中に関数定義可能。非同期通信で取得した値を設定できる!!
const postData = atom(async (get) => {
const id = get(postId);
const response = await fetch(
`https://hacker-news.firebaseio.com/v0/item/${id}.json`
);
return await response.json();
});
function Id() {
// コンポーネント内で利用する場合はuseAtomで値を取得する。
const [id] = useAtom(postId);
const props = useSpring({ from: { id: 0 }, id, reset: true });
return <a.h1>{props.id.to(Math.round)}</a.h1>;
}
function Next() {
const [, set] = useAtom(postId);
return (
<button onClick={() => set((x) => x + 1)}>
<div>→</div>
</button>
);
}
function PostTitle() {
// APIレスポンスの結果を取得する。
const [{ by, title, url, text, time }] = useAtom(postData);
return (
<>
<h2>{by}</h2>
<h6>{new Date(time * 1000).toLocaleDateString("en-US")}</h6>
{title && <h4>{title}</h4>}
<a href={url}>{url}</a>
<p>{text}</p>
</>
);
}
export default function App() {
return (
<Provider>
<Id />
<div>
<Suspense fallback={<h2>Loading...</h2>}>
<PostTitle />
</Suspense>
</div>
<Next />
</Provider>
);
}
参考文献