彻底搞懂 react 的 use client

一、问题背景

这几天接触了下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。
相关推荐
aiweker几秒前
python web开发-Flask 重定向与URL生成完全指南
前端·python·flask
Onion几秒前
CodeWave集成wujie微前端路由跳转思路
前端
设计师小聂!6 分钟前
vue3 - 自定义hook
开发语言·javascript·ecmascript
伍哥的传说7 分钟前
daisyUI 扩展之 pin input 组件开发,极致pin码输入框
前端·javascript·react.js·交互
云小遥36 分钟前
Cornerstone3D 2.x升级调研
前端·数据可视化
李明卫杭州41 分钟前
浅谈JavaScript中Blob对象
前端·javascript
springfe010142 分钟前
Cesium 3D地图 图元 圆柱 图片实现
前端·cesium
meng半颗糖44 分钟前
vue3 双容器自动扩展布局 根据 内容的多少 动态定义宽度
前端·javascript·css·vue.js·elementui·vue3
yt948321 小时前
jquery和CSS3圆形倒计时特效
前端·css3·jquery
teeeeeeemo1 小时前
CSS3 动画基础与技巧
前端·css·笔记·css3