😸
SWRのfetcher関数を、TypeScriptのGenericsを使っていい感じにする
備忘録です。
ReactやNext.jsでfetchを利用するときに、選択肢の1つとして上がるSWRですが、最初使ったときにはuseSWR
の 第二引数である、fetcher関数がよくわかりませんでした。
import useSWR from 'swr'
function Profile() {
const { data, error, isLoading } = useSWR('/api/user', fetcher) // ← なにこれ?
if (error) return <div>failed to load</div>
if (isLoading) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
この記事を見ると、fetcher関数を自分なりにカスタマイズしていくことで、様々なライブラリを利用したり、様々なインターフェースに対応できることがわかります。
一旦私はaxios
でSWRを動かしてみようと試みて、色々試行錯誤した結果、以下のようにGenericsを使っていい感じにできました。
'use client'
import useSWR from 'swr'
import axios, { AxiosResponse } from "axios"
export default function Page() {
type user = {
ID: string,
name: string,
email: string,
}
const fetcher = <T,>(path: string): Promise<T> => axios.get("http://localhost:8080" + path).then((res: AxiosResponse<T>) => res.data)
const { data, error, isLoading } = useSWR<user[]>('/users', fetcher)
if (error) return <div>failed to load</div>
if (isLoading) return <div>loading...</div>
return (
<div>
<h1>Users</h1>
<ul>
{data && data.map((user: user) => (
<li key={user.ID}>
<span>{user.name}</span>
<span>{user.email}</span>
</li>
))}
</ul>
</div>
)
}
fetcher関数にGenericsを利用することで、様々な箇所で汎用的に使えるfetcher関数になりました。
APIのホストも統一されるので、利用側としては pathだけを気にすればいいのでいい感じです。
Discussion