域名 AXUM.RS 将于2025年10月到期。我们无意再对其进行续费,我们希望你能够接续这个域名,让更多 AXUM 开发者继续受益。
  • 方案1️⃣AXUM.RS 域名 = 3000
  • 方案2️⃣方案1️⃣ + 本站所有专题原始 Markdown 文档 = 5000
  • 方案3️⃣方案2️⃣ + 本站原始数据库 = 5500
如果你有意接续这份 AXUM 情怀,请与我们取得联系。
说明:
  1. 如果有人购买 AXUM.RS 域名(方案1️⃣),或者该域名到期,本站将启用新的免费域名继续提供服务。
  2. 如果有人购买了 AXUM.RS 域名,且同时购买了内容和/或数据库(方案2️⃣/方案3️⃣),本站将关闭。届时我们或许会以另一种方式与你再相遇。

组件与渲染

本章讨论新版 Next.js 中变化最大的部分:组件和渲染。

和之前版本相比,Next.js 最大的变化就是:所有组件默认都是服务端组件,相应地,它们使用的就是服务端渲染

之前版本的组件

在之前版本中:

  • 不太严谨地说:除非你使用了 getServerSideProps(),否则可以视为客户端组件和客户端渲染(当然还可能是其它渲染,通过 getXXProps()
  • 可以在组件中直接使用 React 的 useState()useEffect() 等 hook

服务端组件

  • 无须使用 getServerSideProps(),默认就是服务端渲染
  • 无法使用 React 的 useState()useEffect() 等 hook
  • 可以异步获取远程数据
  • 需要使用 "use client" 语句声明该组件是客户端组件
  • 可以使用 React 的 useState()useEffect() 等 hook
  • Next.js 的约定中,有一些是必须是客户端组件

案例:获取IP

我们分别编写服务端组件和客户端组件来通过https://httpbin.org/ip来获取IP。

客户端组件

先从我们熟悉的客户端组件开始。客户端组件其实就是传统的 React 组件,我们通过 useStateuseEffect 来实现:

  • "use client";:告诉 Next.js ,这是一个客户端组件
  • 使用 useState() 来维护ip数据
  • useEffect() 中,通过 fetch() 从远程API中获取数据
  • 客户端组件中的 fetch() 是由浏览器提供的
export default async function IPServer() {
  let ip = "正在获取";
  try {
    const res = await fetch("https://httpbin.org/ip");
    const data = await res.json();
    ip = data.origin;
  } catch (e) {
    ip = "发生错误,请重试";
  }
  return <div>服务端组件获取到的IP:{ip}</div>;
}
  • 无须特别声明,在 Next.js 所有组件默认都是服务端组件
  • 可以使用 await
  • 服务端组件中的 fetch() 是由 Next.js 提供的
import { IPClient, IPServer } from "@/components/Ip";
import Link from "next/link";

export default function Home({ searchParams }) {
  const isClientStr = searchParams.client || "";
  const isClient = isClientStr === "1";
  return (
    <>
      {isClient ? <IPClient /> : <IPServer />}

      <div style={{ display: "flex", gap: "1rem" }}>
        <Link href="/">服务端组件</Link>
        <Link href="/?client=1">客户端组件</Link>
      </div>
    </>
  );
}

本章代码位于03/组件与渲染分支。

要查看完整内容,请先登录