use client
'use client'
指令用于声明组件将在客户端渲染。当你需要实现交互式 UI(如状态管理、事件处理、访问浏览器 API 等)时,应在文件顶部添加该指令。这是 React 的一项特性。
提示:
你无需在每个包含客户端组件的文件中都添加
'use client'
指令。只需在你希望直接在服务端组件中渲染的组件文件顶部添加即可。'use client'
指令定义了客户端与服务端的边界,被加上该指令的文件导出的组件会作为客户端的入口点。
用法
要声明客户端组件的入口点,请在文件顶部(所有 import 语句之前)添加 'use client'
指令:
- TypeScript
- JavaScript
app/components/counter.tsx
'use client'
import { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
)
}
app/components/counter.js
'use client'
import { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
)
}
当使用 'use client'
指令时,客户端组件的 props 必须是可序列化的。也就是说,props 必须采用 React 能够在服务端与客户端之间序列化的数据格式。
- TypeScript
- JavaScript
app/components/counter.tsx
'use client'
export default function Counter({
onClick /* ❌ 函数类型不可序列化 */,
}) {
return (
<div>
<button onClick={onClick}>Increment</button>
</div>
)
}
app/components/counter.js
'use client'
export default function Counter({
onClick /* ❌ 函数类型不可序列化 */,
}) {
return (
<div>
<button onClick={onClick}>Increment</button>
</div>
)
}
在服务端组件中嵌套客户端组件
服务端组件与客户端组件的结合,可以让你构建既高性能又具备交互性的应用:
- 服务端组件:用于静态内容、数据获取和 SEO 友好的元素。
- 客户端组件:用于需要状态、effect 或浏览器 API 的交互式元素。
- 组件组合:可根据需要在服务端组件中嵌套客户端组件,实现服务端与客户端逻辑的清晰分离。
如下示例:
Header
是服务端组件,负责静态内容。Counter
是客户端组件,负责页面内的交互。
- TypeScript
- JavaScript
app/page.tsx
import Header from './header'
import Counter from './counter' // 这是客户端组件
export default function Page() {
return (
<div>
<Header />
<Counter />
</div>
)
}
app/page.js
import Header from './header'
import Counter from './counter' // 这是客户端组件
export default function Page() {
return (
<div>
<Header />
<Counter />
</div>
)
}
参考资料
详见 React 官方文档 关于 'use client'
的说明。