まずは普通に、supabaseでデータ取得をしてみます。
userIdを元に、profileのデータを取得するカスタムフックの一例です。
useProfile.ts
const useProfile = () => {
// userId
const { userId } = useAuthUser()
const [profile, setProfile] = useState<Profile>()
const getProfile = async (id: string) => {
const { data } = await supabase.from('profiles').select('*').eq('id', id).single()
return setProfile(data as Profile)
}
useEffect(() => {
userId && getProfile(userId)
}, [userId])
return {
profile,
}
}
export default useProfile
しかしながらこれだと、useEffectの発火のタイミング次第では無駄な再取得などが起きるかもしれません。
噂によると、どうやらデータをキャッシュなどの仕組みでよしなに取得してくれるライブラリがあるそうです。
それが今回のuseSWRです。
さて、こちらのswrですが基本的な使い方がこうらしいです。
const fetcher = (...args) => fetch(...args).then(res => res.json())
const { data, error, isLoading } = useSWR('/api/user/123', fetcher)
どうやら、useSWRの第一引数に入れたkeyを、fetcherにより取得するようです。
つまり/api/user/123
からのapiレスポンスが必要なので、supabaseのクライアントライブラリとの併用が難しいです。
そこでapiを用意するために、Next.jsのApiRoutesの機能と組み合わせていきたいと思います。
結果的に今回のprofileで例えると、/api/profile/
のようなapiを作成すれば良いかと思います。
以下がNext.jsのApiRoutesで、supabaseのクエリを実行するapiの例です。
pages/api/profile/[userId].tsx
const profileApi = async (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'GET') {
const userId = req.query.userId
const { data, error } = await supabase.from('profiles').select('*').eq('id', userId).single()
if (error) {
return res.status(500).json({ message: error })
}
return res.status(200).json(data)
}
}
export default profileApi
では、作成したapiをswrで使うように、カスタムフックを修正してみます。
useProfile.ts
const useProfile = () => {
const { userId } = useAuthUser()
const { data: profile, error } = useSWR(`/api/profile/${userId}`, fetcher)
return {
profile,
}
}
export default useProfile
こうすることで、supabaseのfetchをNext.jsのapiRoutesのおかげで、swrで行うことができるようになりました!
ただこの方法はだと、
apiのファイルも作らないといけない ⇦ コレ!!!
どのようなクエリが実行されているか想像しにくい などといった問題点を感じています。
より良い使い方を知っている方は、ぜひ教えて頂きたいです!
twitter : https://twitter.com/MukaigawaraYuki
可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。
Read More可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。
Read More