サスペンス
React はまだサスペンスをデータ取得フレームワークである SWR などで使うことを 推奨していません (詳細)。 これらの API は将来的に私たちの調査により変更される可能性があります。
React サスペンスで SWR を使用するには、 suspense
オプションを有効にします。
import { Suspense } from 'react'
import useSWR from 'swr'
function Profile () {
const { data } = useSWR('/api/user', fetcher, { suspense: true })
return <div>hello, {data.name}</div>
}
function App () {
return (
<Suspense fallback={<div>loading...</div>}>
<Profile/>
</Suspense>
)
}
suspense
オプションは、ライフサイクル内では変更できないことに注意してください。
サスペンスモードでの data
は常にフェッチのレスポンスです(よって undefined
かどうかをチェックする必要はありません)。
ただし、エラーが発生した場合は、エラーをキャッチするためにエラーバウンダリー (opens in a new tab)を使う必要があります:
<ErrorBoundary fallback={<h2>Could not fetch posts.</h2>}>
<Suspense fallback={<h1>Loading posts...</h1>}>
<Profile />
</Suspense>
</ErrorBoundary>
サスペンスモードはデータが利用可能になるまでレンダリングを中断します。これは簡単にウォーターフォール問題を引き起こすことを意味します。これを避けるためにはレンダリングの前にリソースをプリフェッチする必要があります。詳細はこちら
注:条件付きフェッチを使用する場合
通常、suspense
を有効にすると、レンダリング時に data
が常に準備ができていることが保証されます:
function Profile () {
const { data } = useSWR('/api/user', fetcher, { suspense: true })
// `data` は決して `undefined` にはなりません
// ...
}
ただし、条件付きフェッチまたは依存フェッチと一緒に使用すると、リクエストが一時停止された場合に data
は undefined
なります:
function Profile () {
const { data } = useSWR(isReady ? '/api/user' : null, fetcher, { suspense: true })
// `isReady` が false のときには `data` は `undefined` になります
// ...
}
この制限に関する技術的な詳細を読みたい場合は、こちらの議論 (opens in a new tab)を確認してください。
サーバサイドレンダリング
サスペンスモードをサーバサイド(Next.js によるプリレンダリングを含む)で使う場合、fallbackData や fallback により初期データが提供されている必要があります。これはサスペンスをサーバサイドでのデータ取得に使うことができないことを意味しており、クライアントサイドでのデータ取得を行うか、フレームワークを通じたデータ取得(Next.js の getStaticProps のような)のどちらかを行う必要があります。これについての議論はこちら (opens in a new tab)です。