データのプリフェッチ
トップレベルのページデータ
SWRのデータをプリフェッチする方法はたくさんあります。トップレベルのリクエストには、rel="preload"
(新しいタブで開きます) を強く推奨します。
<link rel="preload" href="/api/data" as="fetch" crossorigin="anonymous">
HTMLの<head>
内に入れるだけです。簡単、高速、かつネイティブです。
JavaScriptのダウンロードが始まる前でも、HTMLのロード時にデータをプリフェッチします。同じURLへのすべての着信フェッチリクエストは、結果を再利用します(もちろんSWRも含まれます)。
プログラムによるプリフェッチ
SWRは、リソースをプログラムでプリフェッチし、結果をキャッシュに保存するためのpreload
APIを提供します。preload
は、引数としてkey
とfetcher
を受け入れます。
Reactの外でもpreload
を呼び出すことができます。
import { useState } from 'react'
import useSWR, { preload } from 'swr'
const fetcher = (url) => fetch(url).then((res) => res.json())
// Preload the resource before rendering the User component below,
// this prevents potential waterfalls in your application.
// You can also start preloading when hovering the button or link, too.
preload('/api/user', fetcher)
function User() {
const { data } = useSWR('/api/user', fetcher)
...
}
export default function App() {
const [show, setShow] = useState(false)
return (
<div>
<button onClick={() => setShow(true)}>Show User</button>
{show ? <User /> : null}
</div>
)
}
Reactのレンダリングツリー内では、イベントハンドラーやuseEffectでもpreload
を使用できます。
function App({ userId }) {
const [show, setShow] = useState(false)
// preload in effects
useEffect(() => {
preload('/api/user?id=' + userId, fetcher)
}, [userId])
return (
<div>
<button
onClick={() => setShow(true)}
{/* preload in event callbacks */}
onHover={() => preload('/api/user?id=' + userId, fetcher)}
>
Show User
</button>
{show ? <User /> : null}
</div>
)
}
Next.jsのページプリフェッチ (新しいタブで開きます)のようなテクニックと組み合わせることで、次のページとデータを瞬時にロードできます。
Suspenseモードでは、ウォーターフォール問題を回避するためにpreload
を利用する必要があります。
import useSWR, { preload } from 'swr'
// should call before rendering
preload('/api/user', fetcher);
preload('/api/movies', fetcher);
const Page = () => {
// The below useSWR hooks will suspend the rendering, but the requests to `/api/user` and `/api/movies` have started by `preload` already,
// so the waterfall problem doesn't happen.
const { data: user } = useSWR('/api/user', fetcher, { suspense: true });
const { data: movies } = useSWR('/api/movies', fetcher, { suspense: true });
return (
<div>
<User user={user} />
<Movies movies={movies} />
</div>
);
}
データの事前入力
既存のデータをSWRキャッシュに事前に入力する場合は、fallbackData
オプションを使用できます。例えば
useSWR('/api/data', fetcher, { fallbackData: prefetchedData })
SWRがまだデータをフェッチしていない場合、このフックはフォールバックとしてprefetchedData
を返します。
<SWRConfig>
とfallback
オプションを使用して、すべてのSWRフックと複数のキーに対してこれを構成することもできます。詳細については、Next.js SSGとSSRを確認してください。