Next.js での使用
App Router
サーバーコンポーネント
Next.js App Router では、すべてのコンポーネントがデフォルトで React サーバーコンポーネント (RSC) です。 **RSC では SWR からキーのシリアライズ API のみをインポートできます。**
import { unstable_serialize } from 'swr' // ✅ Available in server components
import { unstable_serialize as infinite_unstable_serialize } from 'swr/infinite' // ✅ Available in server components
RSC では利用できないため、SWR から他の API をインポートすることはできません。
import useSWR from 'swr' // ❌ This is not available in server components
クライアントコンポーネント
コンポーネントを 'use client'
ディレクティブでマークするか、クライアントコンポーネントから SWR をインポートすると、両方の方法で SWR クライアントデータフェッチフックを使用できます。
'use client'
import useSWR from 'swr'
export default Page() {
const { data } = useSWR('/api/user', fetcher)
return <h1>{data.name}</h1>
}
サーバーコンポーネント layout
または page
でグローバル設定を構成するために SWRConfig
を使用する必要がある場合は、プロバイダーと設定をセットアップする別のプロバイダークライアントコンポーネントを作成し、それをサーバーコンポーネントページで使用してください。
'use client';
import { SWRConfig } from 'swr'
export const SWRProvider = ({ children }) => {
return <SWRConfig>{children}</SWRConfig>
};
// This is still a server component
import { SWRProvider } from './swr-provider'
export default Page() {
return (
<SWRProvider>
<h1>hello SWR</h1>
</SWRProvider>
)
}
クライアント側データフェッチ
ページに頻繁に更新されるデータが含まれており、データを事前にレンダリングする必要がない場合、SWR は最適であり、特別な設定は必要ありません。必要なのは、useSWR
をインポートして、データを使用するコンポーネント内でフックを使用するだけです。
仕組みは次のとおりです。
- まず、データなしでページをすぐに表示します。欠落しているデータに対してローディング状態を表示できます。
- 次に、クライアント側でデータをフェッチし、準備ができたら表示します。
このアプローチは、たとえば、ユーザーダッシュボードページに適しています。ダッシュボードはプライベートなユーザー固有のページであるため、SEO は関係がなく、ページを事前にレンダリングする必要はありません。データは頻繁に更新されるため、リクエスト時のデータフェッチが必要です。
デフォルトデータによるプリレンダリング
ページを事前にレンダリングする必要がある場合、Next.js は 2 つの形式のプリレンダリング (新しいタブで開く) をサポートしています。**静的生成 (SSG)** と **サーバーサイドレンダリング (SSR)** です。
SWR と共に、SEO のためにページを事前にレンダリングし、クライアント側でキャッシュ、再検証、フォーカストラッキング、インターバルでの再フェッチなどの機能を利用することもできます。
SWRConfig
の fallback
オプションを使用すると、プリフェッチされたデータをすべての SWR フックの初期値として渡すことができます。
たとえば、getStaticProps
を使用する場合
export async function getStaticProps () {
// `getStaticProps` is executed on the server side.
const article = await getArticleFromAPI()
return {
props: {
fallback: {
'/api/article': article
}
}
}
}
function Article() {
// `data` will always be available as it's in `fallback`.
const { data } = useSWR('/api/article', fetcher)
return <h1>{data.title}</h1>
}
export default function Page({ fallback }) {
// SWR hooks inside the `SWRConfig` boundary will use those values.
return (
<SWRConfig value={{ fallback }}>
<Article />
</SWRConfig>
)
}
ページは引き続き事前にレンダリングされます。SEO に対応し、高速な応答が可能ですが、クライアント側では SWR によって完全に機能します。データは動的であり、時間の経過とともに自己更新できます。
Article
コンポーネントは、最初に事前生成されたデータをレンダリングし、ページがハイドレートされた後、最新のデータを再度フェッチして、鮮度を維持します。
複合キー
useSWR
は、array
型および function
型であるキーで使用できます。この種のキーを使用してプリフェッチされたデータを利用するには、fallback
キーを unstable_serialize
でシリアライズする必要があります。
import useSWR, { unstable_serialize } from 'swr'
export async function getStaticProps () {
const article = await getArticleFromAPI(1)
return {
props: {
fallback: {
// unstable_serialize() array style key
[unstable_serialize(['api', 'article', 1])]: article,
}
}
}
}
function Article() {
// using an array style key.
const { data } = useSWR(['api', 'article', 1], fetcher)
return <h1>{data.title}</h1>
}
export default function Page({ fallback }) {
return (
<SWRConfig value={{ fallback }}>
<Article />
</SWRConfig>
)
}