AsyncなJotaiについて調べる
まずは公式のど真ん中のページから
ふつうにこれでSuspendするのか...つよいな
const asyncAtom = atom(async (get) => get(countAtom) * 2)
const [num] = useAtom(asyncAtom)
suspendさせたくないときはloadable
derivedも可能
const anotherAtom = atom(async (get) => (await get(asyncAtom)) / 2)
An interesting pattern that can be achieved with Jotai is switching from async to sync to trigger suspending when wanted.
初期値をstaticに入れておいて、必要に応じてdynamicな値を途中からいれるようなUIにすることもできると。
最初に<SomewhereX />がマウントされたとすると次に<SomewhereX />(or <SomewhereY />)をレンダリングする際はPromiseは解決されているのでfallbackは出ません。
そうか、Reactの外側でPromiseが解決されてるもんね
atom familyでキャッシュ付きページネーション面白いな
// urlをキーとしてasync atomを作成
export const peopleFamily = atomFamily((url: string) =>
atom(async () => {
const {
results: people,
next: nextUrl,
previous: previousUrl
} = await fetchPeople(url);
return { people, nextUrl, previousUrl };
})
);
revalidateTagみたいな
export const versionAtom = atom(0);
export const dataAtom = atom(async (get) => {
get(version);
const response = await fetch(...);
return response.json();
});
いやでもversionAtomの更新はhooksを通じてしか行えないからServer Actionsといっしょには使いづらいか
ネットワーク処理をjotaiのコア機能のみで扱う場合、やりたいことが簡単にはできないことが出てきます。(出来ないことはないと思いますが自前で実装する必要が多いです)
Jotaiでデータフェッチ処理を扱いたい場合、”現時点では”、jotai/queryをおすすめします。RQのhooksで使うのではなく、です。
Tanstackいらなくなるかなと思ってたけど、そうでもないっぽい
上記の問題を改善する為には、並列処理が必要です。並列にPromiseを解決する為には、utilsから提供されるwaitForAllが使えます。
Promise.all的な
おすすめは、jotai-suspenseのusePrepareAtomsです。waitForAllを使ったシンプルなhooksとして提供されています。
こういうのちょっと苦手
atom関数の第2引数がwrite関数です。write関数では何をやるにも自由なので、サイドエフェクトが許されます。
意識してなかったけどたしかに。
あーこれいいな、面白いな
const paramsAtom = atom(...);
const postStatusAtom = atom({ requesting: false, error: null });
const asyncPostAtom = atom(
(get) => get(postStatusAtom),
async (get, set) => {
set(postStatusAtom, { requesting: true, error: null });
const result = await post(get(params));
set(postStatusAtom, { requesting: false, error: result.error });
});
atomicに分かれてると読みやすいし、利用者側に併せてリッチなatomを合成することもできる。
めちゃいい記事だった
guideじゃないページもあるな
loadableよりも直接的に値にアクセスできるunwrap
const unwrapped1Atom = unwrap(delayedCountAtom)
// The value is `undefined` while pending
const unwrapped2Atom = unwrap(delayedCountAtom, (prev) => prev ?? 0)
// The value is `0` initially, and subsequent updates keep the previous value.
そのままだと並列処理になってない点を除けば、Async Atomはかなり素朴に使えそう。
ゆーてもこれはSuspendの設計の問題だから、Tanstackでもおきるか
When using React Query in suspense mode, this pattern of parallelism does not work, since the first query would throw a promise internally and would suspend the component before the other queries run. To get around this, you'll either need to use the useQueries hook (which is suggested) or orchestrate your own parallelism with separate components for each useQuery instance (which is lame).
TanstackのuseQueriesよりかは、jotai-suspenseのほうがSuspenseっぽいか。
きちんとSuspense境界を定めれば大丈夫か?親の表示を早くできそうだけど並列にはならないか