0

0

Nextjs 中的服务器组件与客户端组件 何时以及如何使用它们

碧海醫心

碧海醫心

发布时间:2024-10-24 15:51:01

|

1103人浏览过

|

来源于dev.to

转载

nextjs 中的服务器组件与客户端组件 何时以及如何使用它们

next.js 13 引入了 react server components,使开发人员能够选择渲染组件的位置和方式——无论是在服务器上以提高性能,还是在客户端上以实现交互性。这种灵活性使我们能够构建兼具速度和动态功能的应用程序。

在本文中,我们不仅将探讨基础知识,还将深入探讨如何在客户端组件中使用服务器组件——这是构建动态、高效的应用程序时的常见需求。

了解服务器组件

服务器组件完全在服务器上呈现,不需要任何客户端 javascript。它们非常适合静态内容,例如页眉、页脚,甚至不需要用户交互的数据驱动组件。

示例:简单服务器组件

// app/components/header.js
export default function header() {
  return (
    <header>
      <h1>my static header</h1>
    </header>
  );
}

该组件在服务器上呈现,不涉及任何客户端交互,这意味着它使用更少的 javascript 加载速度更快。

服务器组件的优点

  • 减少 javascript 有效负载:服务器组件减少发送到浏览器的 javascript 量。
  • 改进的数据获取:服务器组件可以获取更接近数据库的数据,从而减少网络延迟。

在服务器组件中获取数据

// app/components/postlist.js
export default async function postlist() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts');
  const posts = await res.json();

  return (
    <ul>
      {posts.slice(0, 5).map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

此 postlist 组件在服务器上获取数据并将预渲染的 html 发送到客户端,确保更快的加载时间。

何时使用客户端组件

当您需要交互性(例如表单输入、事件侦听器或动态内容)时,客户端组件至关重要。这些组件在客户端使用 javascript 来处理用户交互。

示例:用于交互的客户端组件

// app/components/searchbar.js
'use client';  // this makes the component a client component

import { usestate } from 'react';

export default function searchbar() {
  const [searchterm, setsearchterm] = usestate('');

  return (
    <div>
      <input
        type="text"
        value={searchterm}
        onchange={(e) => setsearchterm(e.target.value)}
        placeholder="search..."
      />
      <p>searching for: {searchterm}</p>
    </div>
  );
}

searchbar 是交互式的,因此它需要是一个客户端组件。您只能在客户端组件中使用 usestate 钩子和其他 react 钩子。

您可能有一个组合服务器和客户端组件的用例,所以我们接下来讨论如何做到这一点:

组合服务器和客户端组件

next.js 13 的核心优势是能够组合服务器和客户端组件。最佳实践是默认使用服务器组件,并将客户端组件尽可能深入地推送到组件树中。

示例:组合服务器和客户端组件

// app/layout.js
import searchbar from './components/searchbar';

export default function layout({ children }) {
  return (
    <div>
      <header>my blog</header>
      <searchbar />  {/* client component for interactivity */}
      {children}
    </div>
  );
}

searchbar 组件处理客户端交互性,而布局的其余部分则由服务器渲染,从而在性能和交互性之间提供平衡。

相反,您可能有一个在客户端组件内使用服务器组件的用例。让我们看看如何做到这一点。

如何在客户端组件中使用服务器组件

重要的是要了解服务器组件可以嵌套在客户端组件中,但不能直接导入到其中。要在客户端组件中包含服务器组件,请将其作为子组件或 prop 传递,以避免打破两者之间的边界。

示例:将服务器组件传递给客户端组件

这是一个真实的示例,其中服务器组件作为子组件传递给客户端组件:

// app/components/profile.js (server component)
export default function profile({ user }) {
  return (
    <div>
      <h2>{user.name}</h2>
      <p>email: {user.email}</p>
    </div>
  );
}

// app/components/dashboard.js (client component)
'use client';

import { usestate } from 'react';

export default function dashboard({ children }) {
  const [showprofile, setshowprofile] = usestate(false);

  return (
    <div>
      <button onclick={() => setshowprofile(!showprofile)}>
        {showprofile ? 'hide profile' : 'show profile'}
      </button>

      {showprofile && <div>{children}</div>} {/* server component passed as children */}
    </div>
  );
}

// app/page.js (main page using both components)
import profile from './components/profile';
import dashboard from './components/dashboard';

export default async function page() {
  const user = { name: 'john doe', email: 'john@example.com' };  // static example

  return (
    <div>
      <dashboard>
        <profile user={user} />  {/* passing the server component to client */}
      </dashboard>
    </div>
  );
}

在上面的例子中:

Amazon Nova
Amazon Nova

亚马逊云科技(AWS)推出的一系列生成式AI基础模型

下载
  • profile 是一个服务器组件,用于获取数据或显示静态内容。
  • 仪表板是处理交互的客户端组件(显示/隐藏配置文件)。
  • profile 服务器组件作为子组件传递给仪表板客户端组件。

此模式允许您利用服务器渲染的优势(更少的 javascript,提高性能),同时仍然具有客户端交互性。

第三方库和客户端组件

许多第三方库(例如身份验证提供程序或 ui 组件)都依赖于 react hooks,这些钩子只能在客户端组件中使用。以下是如何通过将第三方库包装在客户端组件中来解决该限制:

示例:使用第三方轮播

// app/components/carousel.js
'use client';

import carousel from 'react-slick';

export default function mycarousel() {
  const settings = { dots: true, infinite: true };
  return (
    <carousel {...settings}>
      <div><h3>slide 1</h3></div>
      <div><h3>slide 2</h3></div>
    </carousel>
  );
}

// app/page.js
import mycarousel from './components/carousel';

export default function page() {
  return (
    <div>
      <h1>welcome to the app</h1>
      <mycarousel />
    </div>
  );
}

通过将第三方react-slick轮播包装在客户端组件中,我们可以在服务器渲染的页面中使用它,同时仍然访问交互性等客户端功能。

处理服务器和客户端组件之间的 props

在服务器和客户端组件之间传递数据时,道具必须是可序列化的(例如字符串、数字、布尔值)。无法传递函数或类实例等复杂对象。

示例:将数据从服务器传递到客户端

// app/page.js (Server Component)
import UserCard from './components/UserCard';

export default async function Page() {
  const user = { name: 'Jane Doe', age: 30 };  // Simple serializable data

  return (
    <div>
      <h1>Welcome to the App</h1>
      <UserCard user={user} />  {/* Passing serializable data to client component */}
    </div>
  );
}

// app/components/UserCard.js (Client Component)
'use client';

export default function UserCard({ user }) {
  return (
    <div>
      <h2>{user.name}</h2>
      <p>Age: {user.age}</p>
    </div>
  );
}

usercard 客户端组件现在可以动态呈现从服务器组件传递的数据,同时确保所有内容保持可序列化,从而顺利通过服务器-客户端边界。

总而言之,用最佳实践来结束这一点将会很有趣。让我们继续下一步:

服务器和客户端组件组合的最佳实践

以下是一些有效组合服务器和客户端组件的技巧:

  1. 默认为服务器组件:尽可能对静态或数据驱动内容使用服务器组件,以减少 javascript 负载并提高性能。

  2. 使用客户端组件进行交互:仅在需要用户交互或浏览器特定 api 的情况下使用客户端组件。

  3. 将客户端组件移至树下:将客户端组件尽可能深地推入组件树中。这允许您的应用程序的更多内容在服务器上呈现,从而提高性能。

  4. 将服务器组件作为子组件传递:如果需要在客户端组件中使用服务器组件,请将其作为子组件或 prop 传递,而不是直接导入它。

结束语:在性能和交互性之间取得平衡

使用 next.js 13,您可以灵活地在服务器和客户端上渲染组件。通过默认使用用于静态内容的服务器组件和用于交互的客户端组件,并通过仔细管理两者之间的边界,您可以构建既快速又动态的应用程序。

通过遵循此处的模式和示例(例如将服务器组件传递到客户端组件并精心组合它们),您将能够利用 next.js 13 的全部功能来创建高性能的交互式 web 应用程序。

快乐编码
我是迈克尔。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1570

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

651

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

1229

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

1205

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

193

2025.07.29

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

131

2025.08.07

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号