Skip to content
文档
Next.js SSG 和 SSR

与 Next.js 一同使用

App Router

Server Components

在 Next.js App Router 中,所有的组件都被默认视为 React Server Components (RSC) 。在 RSC 中您只能 从SWR 引入序列化 Key API

app/page.tsx
import { unstable_serialize } from 'swr' // ✅ 在 Server components 中可用
import { unstable_serialize as infinite_unstable_serialize } from 'swr/infinite' // ✅ 在 Server components 中可用
🚫

您不能从 SWR 引入其他 API ,因为它们在 RSC 中不可用。

app/page.tsx
import useSWR from 'swr' // ❌ 在 Server components 中不可用

Client Components

您可以直接用 'use client' 标记您的组件或者从 Client Components 引入 SWR ,两种方法都允许您使用 SWR 提供的客户端数据获取 Hooks。

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

如果您需要在 Server Components layout 或者 page 中使用 SWRConfig 配置公共设置,请创建一个独立的 Provider Client Component 以初始化 Provider 和配置,然后在Server Component Pages中使用它。

app/swr-provider.tsx
'use client';
import { SWRConfig } from 'swr'
export const SWRProvider = ({ children }) => {
  return <SWRConfig>{children}</SWRConfig>
};
app/page.tsx
// 这仍然是一个 Server Component
import { SWRProvider } from './swr-provider'
export default Page() {
  return (
    <SWRProvider>
      <h1>hello SWR</h1>
    </SWRProvider>
  )
}

客户端数据获取

如果您的页面包含一些频繁更新的数据,而您并不需要预渲染这些数据,SWR 将非常适用并且并不需要特殊的配置:只需要引入 useSWR 然后在任何需要使用数据的组件中使用这个 Hook

以下是它的工作方式:

  • 首先,立即在没有数据的情况下展示页面。您可以显示缺失数据的加载状况。
  • 然后,在客户端获取数据,并在数据准备好时展示它们.

例如,这个方法在用户仪表盘页面上工作得很好。因为仪表板是不公开、用户特定的页面,与 SEO 无关并且页面不需要预渲染。数据频繁更新,需要在请求时获取。

带有默认数据的预渲染

如果页面需要预渲染,Next.js 支持 两种预渲染方式 (opens in a new tab): 静态生成 (SSG) and 服务端渲染 (SSR).

通过使用 SWR, 您可以为了 SEO 预渲染页面, 并同时在客户端享受缓存、重新验证、焦点追踪、定时重新获取等特性。

您可以使用 SWRConfigfallback 选项来将预获取的数据作为所有 SWR Hook 的初始值。

使用 getStaticProps 的例子:

 export async function getStaticProps () {
  // `getStaticProps` 在服务端执行
  const article = await getArticleFromAPI()
  return {
    props: {
      fallback: {
        '/api/article': article
      }
    }
  }
}
 
function Article() {
  // `data` 将始终可用,因为其处于 `fallback` 列表中
  const { data } = useSWR('/api/article', fetcher)
  return <h1>{data.title}</h1>
}
 
export default function Page({ fallback }) {
  // 在 `SWRConfig` 标签内的 SWR hooks 将使用这些值
  return (
    <SWRConfig value={{ fallback }}>
      <Article />
    </SWRConfig>
  )
}

该页面仍然是预先生成,SEO 友好的,并且能够快速反应。然而该页面在客户端侧仍然完全由 SWR 驱动。数据仍然是动态的,且可以自动更新。

💡

Article 组件将先渲染预先生成的数据,并且在页面水合完成后将再次获取最新数据以保持数据最新

复杂关键字

useSWR 可以与 arrayfunction 类型的 key 一同使用. 若要通过这些类型的 key 使用预先获取的数据,需要用 unstable_serialize 序列化 fallback key.

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