Skip to content
开发文档
Next.js SSG 和 SSR

与 Next.js 一起使用

¥Usage with Next.js

应用路由

¥App Router

服务器组件

¥Server Components

在 Next.js App Router 中,所有组件默认都是 React Server Components (RSC)。你只能从 RSC 中的 SWR 导入键序列化 API。

¥In Next.js App Router, all components are React Server Components (RSC) by default. You could only import the key serialization APIs from SWR in RSC.

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 中不可用。

¥You could not import any other APIs from SWR since they are not available in RSC.

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

客户端组件

¥Client Components

你可以使用 'use client' 指令标记你的组件或从客户端组件导入 SWR,这两种方式都允许你使用 SWR 客户端数据请求钩子。

¥You can mark your components with 'use client' directive or import SWR from client components, both ways will allow you to use the SWR client data fetching hooks.

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

如果你需要使用 SWRConfig 在服务器组件 layoutpage 中配置全局设置,请创建一个单独的提供程序客户端组件来设置提供程序和配置,然后在服务器组件页面中使用它。

¥If you need to use SWRConfig to configure global settings in server components layout or page, creating a separate provider client component to setup the provider and configuration then use it in the server component pages.

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

客户端数据请求

¥Client Side Data Fetching

如果你的页面包含频繁更新的数据,并且不需要预渲染数据,则 SWR 非常适合,无需特殊设置:只需导入 useSWR 并在使用该数据的任何组件内使用该钩子即可。

¥If your page contains frequently updating data, and you don’t need to pre-render the data, SWR is a perfect fit and no special setup is needed: just import useSWR and use the hook inside any components that use the data.

它的工作原理如下:

¥Here’s how it works:

  • 首先,立即显示没有数据的页面。你可以显示缺失数据的加载状态。

    ¥First, immediately show the page without data. You can show loading states for missing data.

  • 然后,在客户端获取数据并在准备好后显示它。

    ¥Then, fetch the data on the client side and display it when ready.

例如,这种方法适用于用户仪表板页面。由于仪表板是私有的、特定于用户的页面,因此 SEO 不相关,并且页面不需要预渲染。数据更新频繁,需要请求时获取数据。

¥This approach works well for user dashboard pages, for example. Because a dashboard is a private, user-specific page, SEO is not relevant and the page doesn’t need to be pre-rendered. The data is frequently updated, which requires request-time data fetching.

使用默认数据预渲染

¥Pre-rendering with Default Data

如果页面必须预渲染,Next.js 支持 预渲染的 2 种形式 (opens in a new tab):静态生成(SSG)和服务器端渲染(SSR)。

¥If the page must be pre-rendered, Next.js supports 2 forms of pre-rendering (opens in a new tab): Static Generation (SSG) and Server-side Rendering (SSR).

与 SWR 一起,你可以预渲染页面以进行 SEO,并且还可以在客户端提供缓存、重新验证、焦点跟踪、按时间间隔重新获取等功能。

¥Together with SWR, you can pre-render the page for SEO, and also have features such as caching, revalidation, focus tracking, refetching on interval on the client side.

你可以使用 SWRConfigfallback 选项将预请求的数据作为所有 SWR 钩子的初始值传递。

¥You can use the fallback option of SWRConfig to pass the pre-fetched data as the initial value of all SWR hooks.

getStaticProps 为例:

¥For example with 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 提供支持。数据可以是动态的,并且可以随着时间的推移进行自我更新。

¥The page is still pre-rendered. It's SEO friendly, fast to response, but also fully powered by SWR on the client side. The data can be dynamic and self-updated over time.

💡

Article 组件会先渲染预先生成的数据,页面水合后,会再次获取最新数据以保持刷新。

¥The Article component will render the pre-generated data first, and after the page is hydrated, it will fetch the latest data again to keep it refresh.

复合键

¥Complex Keys

useSWR 可与 arrayfunction 类型的键一起使用。使用带有这些类型的键的预请求数据需要将 fallback 键与 unstable_serialize 序列化。

¥useSWR can be used with keys that are array and function types. Utilizing pre-fetched data with these kinds of keys requires serializing the fallback keys with 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>
  )
}