你在 Next.js 中用错 "use client" 了吗?

随着 Next.js 13 和 14 将服务器组件设为默认,这看似是一个改变游戏规则的举措------开发人员开在每个文件上添加 "use client"。

但且慢------你真的知道何时该使用它吗?

还是说,你只是因为害怕而在每个文件上添加它,希望它能修复水合错误?

null

这种情况是否很熟悉?

🚨 "为什么这个组件没有渲染?"

🚨 "为什么这里不能使用状态?"

🚨 "不管怎样------只要添加 'use client' 就可以继续了。"

就这样,你完全错过了服务器组件的意义。

让我们正确地分解一下:

1️⃣ 何时应该使用 "use client"?

2️⃣ 何时应该避免使用它?

3️⃣ 如何正确地构建你的应用程序?

"use client" 到底有什么作用?

在指责 "use client" 之前,让我们先明确它的实际功能。

默认情况下,Next.js 将组件视为服务器组件,这意味着:

✅ 它们在服务器上执行。

✅ 它们不会将不必要的 JavaScript 发送到浏览器。

✅ 它们可以安全地获取数据。

但一旦你添加了 "use client",一切都会改变:

❌ 组件变成了一个客户端组件。

❌ 它将失去对服务器端功能(如直接使用 fetch())的访问权限。

❌ JavaScript 会被发送到浏览器,影响性能。

何时应该使用 "use client"?

并非每个组件都需要成为客户端组件。但以下情况确实需要:

✅ 使用状态或钩子(如 useStateuseEffectuseContext 等)的组件。

jsx 复制代码
"use client";

import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)} className="p-2 bg-blue-500">
      Count: {count}
    </button>
  );
}

服务器组件没有状态------而且永远不会

由于服务器组件不在浏览器中运行,因此它们无法管理状态。

因此,如果组件依赖于 useStateuseEffect,你别无选择------必须将其声明为客户端组件。

何时确实需要 "use client"?

✅ 事件处理程序(如 onClick、onChange、onSubmit 等)

✅ 浏览器 API(如 localStorage、window、document 等)

✅ 上下文提供程序(React 上下文必须是客户端组件)

何时应避免使用 "use client"?

🚨 如果不需要,就不要使用它。

以下是许多开发人员出错的地方:

❌ 不需要所有内容包装在客户端组件中

jsx 复制代码
// ❌ 这是不良实践
"use client";

export default function StaticContent() {
  return <h1 className="text-xl">这本应是一个服务器组件</h1>;
}

该组件无需 "use client",因为它完全是静态的。

强制它在客户端运行只会增加降低性能。

本可以在服务器端处理,而在客户端获取数据

jsx 复制代码
// ❌ 不好:在客户端组件中获取数据
"use client";

import { useState, useEffect } from "react";

export default function Users() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch("/api/users")
      .then((res) => res.json())
      .then((data) => setUsers(data));
  }, []);

  return (
    <ul>
      {users.map((user) => (
      <li key={user.id}>{user.name}</li>
    ))}
    </ul>
  );
}

更好的方法:

在服务器端而不是客户端获取数据。

✅ 好:在服务器组件中获取数据

jsx 复制代码
export default async function Users() {
  const res = await fetch("https://jsonplaceholder.typicode.com/users");
  const users = await res.json();

  return (
    <ul>
      {users.map((user) => (
      <li key={user.id}>{user.name}</li>
    ))}
    </ul>
  );
}

为什么这样更好:

在服务器端获取数据有助于避免不必要的 JavaScript 传输到浏览器,确保更快的页面加载时间。

通过在服务器端获取数据,数据在页面渲染之前就已经加载,从而减轻了客户端的负担。

如何正确构建组件

与其盲目地在每个地方添加 "use client",更好的方法是将组件分为:

✅ 服务器组件(默认使用)

✅ 客户端组件(仅在绝对必要时使用)

这样可以确保最佳性能,并避免不必要的复杂性。

jsx 复制代码
// 服务器组件
import Counter from "./Counter";

export default function Page() {
  return (
    <div>
      <h1 className="text-xl">Hello, Next.js</h1>
      <Counter />
    </div>
  );
}
jsx 复制代码
// 客户端组件(Counter.tsx)
"use client";

import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}

为什么这样更好?

Page 组件保持为服务器组件(经过优化,没有额外的 JavaScript)。

Counter 组件是客户端组件(因为它需要状态)。

🔹 除非组件需要状态或事件处理程序,否则不要使用 "use client"。

🔹 将应用程序的大部分保持为服务器端渲染 以获得更好的性能。

🔹 仅在必要时使用 "use client" 并正确构建客户端组件。

原文:dev.to/joodi/are-y...

相关推荐
鹏多多1 小时前
OpenSpec+SDD规范驱动AI Agent开发项目实战指南
前端·vue.js·react.js
叶小树咯1 小时前
React 为什么不能像 Vue 那样 state.count++
前端·react.js
卡卡军2 小时前
🌈 react-sketch-ruler v3 升级之旅:当 React 遇上跨框架标尺引擎
前端·react.js
AI周红伟5 小时前
长鑫科技存储之王:存储三强对比:三星、SK海力士 vs 长鑫科技
数据库·人工智能·科技·react.js·架构·langchain
右耳朵猫AI5 小时前
React技术周刊 2026年第20周
前端·react.js·前端框架
光影少年6 小时前
react全局状态、局部状态、服务端状态如何选型
前端·react.js·掘金·金石计划
Java陈序员6 小时前
主流数据库通吃!一款开源实用的数据库备份管理工具!
react.js·postgresql·go
孟陬7 小时前
首次上榜新项目 HyperFrames(22k Star):HTML → MP4 一句话生成视频
react.js·node.js·html
喵个咪1 天前
Headless 后端实践:基于Go的企业级多栈管理系统脚手架
前端·vue.js·react.js
代码N年归来仍是新手村成员1 天前
【AWS】Lambda 初识与服务部署
javascript·react.js·ai·node.js·云计算·ai编程·aws