组件与渲染

之前版本的组件

在之前版本中:

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

服务端组件

现在 Next.js 默认所有组件都是服务端组件:

  • 需要使用 "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/组件与渲染分支。

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