useSWRでPromise.allを使って複数のリソースを読み込む 2021.07.21
環境構築
Next.jsのアプリを作成。
% npx create-next-app
✔ What is your project named? … nextjs-useswr-promise-all
Creating a new Next.js app in /Users/same/apps/nextjs-useswr-promise-all.
#...
% cd nextjs-useswr-promise-all
useSWRをインストール。
% yarn add swr
アプリを起動。
% yarn dev
fetcher関数でPromise.allを返す
useSWRフックの第1引数に配列を渡すと、fetcher関数では引数に展開されるので、引数から複数のPromiseを作成してPromise.allで返すようにすれば複数リソースの読み込みに対応できる。
function fetcher(...urls) {
const f = url => fetch(url).then(r => r.json())
return Promise.all(urls.map(f))
}
複数の引数の説明はあるものの、こういった使い方については公式の記載はないようだ。
以下のようなカスタムフックを作成。複数の気象予報情報を読み込んでみる。
import useSWR from 'swr'
function fetcher(...urls) {
const f = url => fetch(url).then(r => r.json())
return Promise.all(urls.map(f))
}
function useWeatherForecastRepository() {
const { data, error } = useSWR([
'https://www.jma.go.jp/bosai/forecast/data/forecast/130000.json',
'https://www.jma.go.jp/bosai/forecast/data/forecast/140000.json',
'https://www.jma.go.jp/bosai/forecast/data/forecast/150000.json',
],
fetcher,
)
return {
data: data ? data.flat() : [],
isLoading: !data && !error,
isError: error,
}
}
export default useWeatherForecastRepository
Viewの作成
import useWeatherForecastRepository from '../repositories/useWeatherForecastRepository'
export default function Home() {
const { data, isLoading, isError } = useWeatherForecastRepository()
return (
<div>
{isLoading ? (
<div>Loading...</div>
) : isError ? (
<div>Error!</div>
) : (
<div>
{data.map((d, i) => (
<div key={i}>{d.reportDatetime} {d.publishingOffice}</div>
))}
</div>
)}
</div>
)
}
出力
2021-07-21T11:00:00+09:00 気象庁
2021-07-21T11:00:00+09:00 気象庁
2021-07-21T11:00:00+09:00 横浜地方気象台
2021-07-21T11:00:00+09:00 横浜地方気象台
2021-07-21T11:00:00+09:00 新潟地方気象台
2021-07-21T11:00:00+09:00 新潟地方気象台
今回の場合、useSWRフックのデータは2次元配列で返ってくるので事前にflat()
している。
useSWRフックで複数のリソースを読み込むことができた。