polidog lab

Top About Rss
2022年03月25日

next/router + useApidaSWRでidを指定してデータ取得する方法

※CSR前提のお話です。

nextjsで詳細ページでデータを取得する場合にidを取得するみたいなことはよくやる。

  const router = useRouter();
	const { id } = router.query

しかしこの場合レンダリング時にidが取得できないことが…
router.isReady状態じゃないとqueryパラメータが取得できないですよね。

router.isReadyじゃない場合の問題点

const router = useRouter();
const { id } = router.query
const { data, error } = useAspidaSWR(
  client.api.v1.projects._id(id as number)
)

例えば上記のコードは、router.isReady が trueじゃないと id が undefinedになってしまう。
なので、https://localhost/api/projects/undefined みたいなリクエストがサーバ側に送られてしまいます。

これは流石に微妙なのでなんとかしたい。

useSWRの場合

// SWRの場合の解決方法
const router = useRouter();
const { id } = router.query
const { data: projects } = useSWR(id ? `/api/projects?uid=${id}` : null, fetcher)

みたいな形で対応できます。 そうです。わたしがReactをシンプルにするSWRです。

しかしuseApidaSWRの場合は、第一引数はnullが許容されていないので、この実装は無理です…

useApidaWRでの解決方法

型情報を見ていたら、optionsのパラメータに enabled という値があります。
aspida/index.ts at 858ecc257bba5cb68a9ae8d2bbf6ad5f043076a4 · aspida/aspida · GitHub

SWRのキーを取得する処理でなんとなくenabledじゃないとkeyをnullにするっぽい処理がはいってあtので、useSWRと同じようなことができそうだなと。
aspida/index.ts at 858ecc257bba5cb68a9ae8d2bbf6ad5f043076a4 · aspida/aspida · GitHub

ということで、以下のような実装をしてみたところうまく動きました。

const router = useRouter();
const { id } = router.query
const { data, error } = useAspidaSWR(
  client.api.v1.projects._id(id as number),
  {
    enabled: id !== undefined,
  }
)

id as number してて負けている気もするけど、今の所この実装しか思い浮かびません。 もっと良い方法があったら誰か教えて下さい…。

comments powered by Disqus