Server Components
- 页面和布局默认是 Server Components。官方说明里明确提到:默认的 layouts 和 pages 是 Server Components
- 默认优先 Server Component,只有需要交互、浏览器 API、客户端状态时才切到 Client Component
server component和ssr
- Server Component 是“组件类型”,SSR 是“渲染方式”
- Server Components 定义为一种在独立服务器环境中运行的组件;而 Next.js 对 SSR 的定义是:每次请求都在服务器上生成页面 HTM
Server Components vs Client Component
Server Component
运行在服务端,特点:
- 可以直接访问服务端资源
- 可以在组件里直接获取数据
- 不会把服务端逻辑和敏感信息发到客户端
- 输出是渲染结果和 RSC payload
- 更有利于减少客户端 JS 体积
为什么说 Server Component 有利于性能?
- 不会把组件逻辑直接打到客户端 bundle
- 可以在服务端直接获取数据
- 可以在服务端利用缓存
- 可以避免把敏感逻辑暴露给浏览器
Client Component
需要在文件顶部写:
'use client'
特点:
- 可以使用
useState、useEffect - 可以使用浏览器 API
- 可以绑定点击事件等交互
- 会进入客户端 bundle
混合使用 Server Components、 Client Component、 SSR
- 页面本身默认就是 Server Component
- 页面的数据是动态请求的数据,这里就是SSR
- 交互部分拆成 Client Component,嵌进 Server Component 页面
// app/users/SearchBox.tsx
'use client'
import { useState } from 'react'
export default function SearchBox() {
const [keyword, setKeyword] = useState('')
return (
<input
value={keyword}
onChange={(e) => setKeyword(e.target.value)}
placeholder="搜索用户"
/>
)
}
- page.tsx
page.tsx是 Server Componentfetch(..., { cache: 'no-store' })或dynamic = 'force-dynamic'会让页面按请求动态渲染,也就是 SSR- export const dynamic = 'force-dynamic' , 强制这个路由段按“请求时动态渲染”处理,而不是静态预渲染
// app/users/page.tsx
import SearchBox from './SearchBox'
export const dynamic = 'force-dynamic'
async function getUsers() {
const res = await fetch('https://api.example.com/users', {
cache: 'no-store',
})
return res.json()
}
export default async function UsersPage() {
const users = await getUsers()
return (
<div>
<SearchBox />
<ul>
{users.map((user: any) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
)
}