SWRで複数の引数を渡して使う方法
SWR、便利ですよね。SWRはデータ取得のためのReact Hooksライブラリです。
SWR は、まずキャッシュからデータを返し(stale)、次にフェッチリクエストを送り(revalidate)、最後に最新のデータを持ってくるという戦略です。
SWRを使うことでコードをシンプルにし、かつサーバーからのデータ取得乱発を避けることができます。例えばaxiosを使ってデータを取得する場合、コードはこうなります。
const fetchData = async () => {
try {
const response = await fetch(
`https://xxx.../v1/data`,
{
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
},
});
const data = await response.json();
} catch (error) {
console.error('読み込みに失敗しました。', error);
}
};
fetchData();
tokenを渡して認証を通し、データを受け取っています。
これを実装した場合、コンポーネントが読み込まれるたびにサーバーと通信を行い、データを取得することになります。
SWRを使うと
import useSWR from 'swr'
function Profile() {
const { data, error, isLoading } = useSWR('https://xxx.../v1/data', fetcher)
if (error) return <div>failed to load</div>
if (isLoading) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
公式コードにある通り、これだけのコードで済むようになり、見通しもよくなります。
(tokenを渡してないので実際には動きません、後半で実際に動くコードをのせています)
useSWRの第一引数はkeyです。このkeyは保存ファイル名みたいなもので、このkey名でデータをキャッシュし、またキャッシュがあるかどうかを調べます。
第二引数は関数です。この関数を動かしてデータを取得してきます。かんたんなfetcher関数はこのように定義できます。
const fetcher = (...args) => fetch(...args).then(res => res.json())
では最初のコードのようにtokenなどの引数を渡したい場合はどうすればいいでしょうか。
const shouldFetch = (token) => !!token;
const { data: currentData } = useSWR(shouldFetch(token) ? ['/v1/data', token] : null, ([url, token]) => fetchCurrentData(url, token))
まず、tokenがある場合にのみデータを返すようにしています。
第一引数には['/v1/data', token]としており、このように複数の引数を配列で渡すことができます。つぎにtokenが存在するタイミングでfetchCurrentDataが実行され、第一引数として['/v1/data', token]が渡されます。次にURLとtokenを引数としてデータを取得しています。
呼び出されるfetchを行う関数はこのようになっています。
import { fetcher } from "@/api/fetcher";
export const fetchCurrentData = async (url: string, token: string) => {
const response = await fetcher({
url: `${url}`,
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
});
return response;
};
データを取得したタイミングでデータをセットしたい場合はuseEffectを使います。
const [currentData, setCurrentData] = useState(null);
useEffect(() => {
if (currentData) {
setTeamList(currentData);
}
}, [currentData, setCurrentData]);
SWRはお手軽で便利なHookなので積極的に使っていきたいところです。
Discussion