跳至内容
文档
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 支持 两种预渲染形式 (在新标签页中打开)静态生成 (SSG)服务器端渲染 (SSR)

与 SWR 结合使用,您可以为 SEO 预渲染页面,还可以获得缓存、重新验证、焦点跟踪、在客户端按时间间隔重新获取等功能。

您可以使用 fallback 选项 SWRConfig 将预取的数据作为所有 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 组件将首先渲染预生成的数据,并且在页面完成 hydration 后,它将再次获取最新数据以保持其新鲜度。

复杂键

useSWR 可用于 arrayfunction 类型的键。利用预取数据使用这些类型的键需要使用 unstable_serializefallback 键进行序列化。

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