跳至內容
文件
Next.js SSG 和 SSR

搭配 Next.js 使用

App Router

伺服器元件

在 Next.js App Router 中,所有元件預設都是 React 伺服器元件 (RSC)。您只能在 RSC 中匯入 SWR 的鍵序列化 API。

app/page.tsx
import { unstable_serialize } from 'swr' // ✅ Available in server components
import { unstable_serialize as infinite_unstable_serialize } from 'swr/infinite' // ✅ Available in server components
🚫

您無法從 SWR 匯入任何其他 API,因為它們在 RSC 中不可用。

app/page.tsx
import useSWR from 'swr' // ❌ This is not available in server components

客戶端元件

您可以使用 'use client' 指令標記您的元件,或從客戶端元件匯入 SWR,兩種方式都允許您使用 SWR 客戶端資料獲取鉤子。

app/page.tsx
'use client'
import useSWR from 'swr'
export default Page() {
  const { data } = useSWR('/api/user', fetcher)
  return <h1>{data.name}</h1>
}

如果您需要在伺服器元件 layoutpage 中使用 SWRConfig 來設定全域設定,請建立一個單獨的提供器客戶端元件來設定提供器和設定,然後在伺服器元件頁面中使用它。

app/swr-provider.tsx
'use client';
import { SWRConfig } from 'swr'
export const SWRProvider = ({ children }) => {
  return <SWRConfig>{children}</SWRConfig>
};
app/page.tsx
// 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,並在客戶端上擁有快取、重新驗證、焦點追蹤、間隔重新獲取等功能。

您可以使用 SWRConfigfallback 選項,將預先獲取的資料作為所有 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 可以與 arrayfunction 類型鍵一起使用。使用預先獲取的資料與這些鍵需要使用 unstable_serialize 序列化 fallback 鍵。

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>
  )
}