一、问题背景
这几天接触了下next.js 13版本,遇到了下面的问题: This React hook only works in a client component.
。
难道直接加use client?那什么时候加,什么时候不加了。看了react官方文档,依然云里雾里。决定整理下这块,争取下次碰到手拿把掐。

二、use client 是啥
官方解释是:'use client'
标记在客户端运行的代码。在文件顶部添加 'use client' 以将模块及其传递的依赖项标记为客户端代码。对于使用 React 服务器组件的应用程序,默认情况下是由服务器渲染的。'use client' 在服务器客户端边界中引入了 模块依赖树 ,从而有效地创建了一个客户端模块的子树。
说实话,作为一个对前端接触不深的研发,看了上面的翻译想打人,到底说的是啥?实际这个英文名字有问题,use client更好的翻译是 use interactive
,与之相对的是use server,应该是 use action。
- use client 不是在客户端渲染的意思,而是在客户端可以使用的钩子,比如 useState,点击事件等。将这个指令放在文件顶部,表示与客户端交互。
- use server 表示使用服务端的api,如查询api token,与数据库交互。默认都是use server。
这里面离不开一个概念叫服务端渲染(ssr),从网上找了个图如下:


可以看到use client的时候,代码是在客户端下载并渲染的,无法使用服务端api。相应的,服务端渲染的时候,处理完在传输到客户端,因此可以使用服务端的api。
三、什么时候用和不用 use client
1、必须使用:简单说就是必须用的时候才用,尽量不用。 以下是必须用的场景:
-
使用浏览器的 web 存储 API、音频和视频处理 API 以及有关设备硬件 API 等 其他 API
-
引用的第三方库可能依赖于组件 Hook 或客户端 API。使用以下 React API 中的任何一个的第三方组件必须在客户端上运行:
- createContext
- react 和 react-dom Hook,但不包括 use 和 useId
- forwardRef
- memo
- startTransition
如果这些库使用了客户端 API,例如向 DOM 插入元素或查看本机图片
2、不要用:在太高的层级 如下图,本来只有comment是client渲染,结果在在Article层级使用了use client,则下面的组件都成了客户端渲染。

因此尽量在更小的Comment层级引用:
javascript
// 新建一个 Comment 组件
"use client";
export default function Comment() {
return (
<button onClick={() => alert("comment!")}>Upvote</button>
);
}
3、不要用:需要使用服务端的数据,如api token等,避免暴露到客户端 4、不要用:需要提高渲染速度
四、 额外补充
组件被 client component引用则是client,被server component 引用则是server。比如下面的button:
javascript
export default function LikeButton() {
return (
<div onClick={() => console.log('like click')}>
like
</div>
)
}
javascript
'use client'
function ClientComponent() {
const [count, setCount] = useClient(() => {
// Only run this hook in the client-side environment
const [localCount, setLocalCount] = useState(0);
return [localCount, setLocalCount];
});
return (
<div>
<LikeButton/>
<button onClick={() => setCount(count + 1)}>Increment</button>
Count: {count}
</div>
);
}
javascript
'use server'
function ServerComponent() {
const data = useServer(() => {
// Fetch data or perform operations that are server-only
return fetchLikeData();
});
return <div>Like Data: {data} <LikeButton/></div>;
}
五、简单总结下
使用use client或者use server有两个影响因素:性能和安全性。
- 尽量使用use server,在服务端渲染提高性能和安全性。
- 对于必须使用客户端api或者使用state则添加 use client。
