跳到主要内容

客户端渲染(CSR)

在使用 React 的客户端渲染(CSR)中,浏览器下载最小的 HTML 页面和页面所需的 JavaScript。然后使用 JavaScript 更新 DOM 并渲染页面。当应用首次加载时,用户可能会注意到在看到完整页面之前有轻微的延迟,这是因为在所有 JavaScript 下载、解析和执行完成之前,页面不会完全渲染。

页面首次加载后,导航到同一网站的其他页面通常会更快,因为只需要获取必要的数据,JavaScript 可以重新渲染页面的部分内容,而无需完整的页面刷新。

在 Next.js 中,你可以通过两种方式实现客户端渲染:

  1. 在页面内使用 React 的 useEffect() hook,而不是服务端渲染方法(getStaticPropsgetServerSideProps)。
  2. 使用像 SWRTanStack Query 这样的数据获取库在客户端获取数据(推荐)。

以下是在 Next.js 页面中使用 useEffect() 的示例:

pages/index.js
import React, { useState, useEffect } from 'react'

export function Page() {
const [data, setData] = useState(null)

useEffect(() => {
const fetchData = async () => {
const response = await fetch('https://api.example.com/data')
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const result = await response.json()
setData(result)
}

fetchData().catch((e) => {
// 根据需要处理错误
console.error('获取数据时发生错误:', e)
})
}, [])

return <p>{data ? `你的数据:${data}` : '加载中...'}</p>
}

在上面的示例中,组件首先渲染 加载中...。然后,一旦获取数据,它会重新渲染并显示数据。

虽然在 useEffect 中获取数据是你可能在较旧的 React 应用中看到的模式,但我们建议使用数据获取库以获得更好的性能、缓存、乐观更新等。以下是使用 SWR 在客户端获取数据的最小示例:

pages/index.js
import useSWR from 'swr'

export function Page() {
const { data, error, isLoading } = useSWR(
'https://api.example.com/data',
fetcher
)

if (error) return <p>加载失败。</p>
if (isLoading) return <p>加载中...</p>

return <p>你的数据:{data}</p>
}

提示

请记住,CSR 可能会影响 SEO。某些搜索引擎爬虫可能不会执行 JavaScript,因此只能看到应用的初始空状态或加载状态。对于网络连接或设备较慢的用户,这也可能导致性能问题,因为他们需要等待所有 JavaScript 加载并运行才能看到完整的页面。Next.js 提倡一种混合方法,允许你根据应用中每个页面的需求组合使用服务端渲染静态站点生成和客户端渲染。在 App 路由中,你还可以使用 Loading UI with Suspense 在页面渲染时显示加载指示器。