Skip to content
ドキュメント
サスペンス

サスペンス

🚨

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` にはなりません
  // ...
}

ただし、条件付きフェッチまたは依存フェッチと一緒に使用すると、リクエストが一時停止された場合に dataundefined なります:

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)です。