彻底搞懂 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。
相关推荐
葡萄城技术团队2 小时前
1000 人协同压测的环境瓶颈排查:CPU 争用与 Wi\-Fi
前端
excel3 小时前
Marked 与 Markdown 有什么区别?该怎么选?
前端
Da Da 泓4 小时前
五子棋 Web 端测试用例报告
前端·网络·websocket·网络协议·测试用例·项目
zxcvb1535 小时前
远程查看本地文档:一条轻量 Web 文件服务的工程化链路
前端·远程查看文档
niucloud-admin5 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
程序员大阳5 小时前
副队长JavaScript教程(50)-DOM:网页开发的起点
javascript·dom·es·节点·概念·document·关系
北岛贰5 小时前
啵啵音乐迎来全新升级!
前端
hkNaruto7 小时前
【AI】基于大模型的AI游戏地图生成、控制方案:AI Native Game Harness 迁移操作手册
前端·人工智能·游戏
IT_陈寒7 小时前
Java序列化踩坑记:对象循环引用让我加班两小时
前端·人工智能·后端
Acro7 小时前
快给macOS 上的Grok Bot换一套皮肤
前端