发布于 2026-01-06 2 阅读
0

Next.js 13.4 的服务器操作和数据获取 AWS AI LIVE!

Next.js 13.4 的服务器操作和数据获取

AWS AI 直播!

作者:维克多·乌玛

概述

在 Web 开发中,提供流畅的用户体验和结构化的数据检索至关重要。Next.js 是一个强大的 React 框架,已成为开发者优化服务器端渲染 (SSR) 和客户端渲染 (CSR) 功能的首选。Next.js 的一个关键优势在于其全面的数据获取和服务器端操作工具包。

理解数据获取的基础知识对于充分发挥 Next.js 的强大功能至关重要。在本教程中,我们将深入探讨 Next.js 的数据获取和服务器操作,以及如何在应用程序中使用和管理这些功能。无论您是经验丰富的 Next.js 开发人员,还是初次接触该框架,本文都将为您提供宝贵的见解和实用示例,助您大幅提升 Web 应用程序的性能。

服务器端操作是 Next.js 的一项早期功能,它允许您构建自定义服务器端点来处理特定的操作和数据操作。Next.js API 路由为高效实现服务器端操作提供了强大的基础,无缝地连接了客户端和服务器。我们将深入探讨创建 API 路由、处理客户端-服务器通信以及实现服务器端功能的细节。

我们将介绍以下步骤:

Next.js 基础知识

Next.js 是一个基于 React 构建的强大框架,它简化并改进了现代前端应用程序的构建。它结合了服务端渲染 (SSR) 和客户端渲染 (CSR) 的最佳特性,为开发者提供了灵活性和性能优化。

Next.js 中的服务器端渲染 (SSR) 与客户端渲染 (CSR)

服务器端渲染是指在服务器端生成网页的 HTML 代码并将其发送给客户端。这种方法可以缩短页面初始加载时间,并有助于搜索引擎优化 (SEO),因为搜索引擎爬虫可以轻松解析完全渲染的 HTML 代码。Next.js 在服务器端渲染方面表现出色,允许您动态或静态地预渲染页面。

另一方面,客户端渲染依赖于 JavaScript 在客户端浏览器上渲染网页。这种方法提供了交互性和动态内容更新,但可能会导致页面初始加载速度较慢。Next.js 支持混合渲染,允许您根据应用程序的需求在服务器端渲染和客户端渲染之间进行选择。

Next.js 的优势

  1. 简化安装:Next.js 提供了一个功能齐全的框架,简化了安装过程。它内置了路由、webpack 配置和热模块替换功能,为您节省时间和精力。
  2. 自动代码分割:Next.js 会智能地将代码分割成更小的块,从而加快页面初始加载速度。它只加载当前页面所需的 JavaScript 代码,减少带宽占用并优化性能。
  3. 轻松实现服务器端渲染:Next.js 让服务器端渲染变得无缝衔接。借助 `getData()` 和 `getData()` 等函数getStaticPropsgetServerSideProps您可以在服务器端渲染过程中获取数据,确保页面在渲染前拥有必要的数据。这对于静态生成和动态渲染场景尤为有用。

Next.js 中的数据获取

数据获取是 Web 开发中至关重要的一环,Next.js 提供了多种内置方法来处理数据获取和渲染。这些方法允许您根据具体需求,在服务器端渲染过程中或客户端获取数据。接下来,我们将探讨 Next.js 提供的各种数据获取技术,并通过代码示例了解如何实现它们。

客户端数据获取

Next.js 提供了一些函数,可以在客户端获取数据,从而实现动态更新而无需重新加载整个页面。最常用的函数来自useEffectReact,它允许我们在组件渲染完成后执行代码。在useEffect钩子函数中,我们可以使用fetchAPI 或任何其他数据获取库从 API 端点检索数据。

import { useEffect, useState } from "react";

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch("https://api.example.com/data");
      const data = await response.json();
      setData(data);
    };

    fetchData();
  }, []);

  return (
    <div>
      {/* Display the fetched data */}
      {data && <p>{data.message}</p>}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

在上面的代码中,我们定义了一个函数式组件MyComponent,它使用 API 从 API 端点获取数据。获取的数据通过函数fetch存储在状态变量中。我们使用带有空依赖数组的钩子来确保数据获取仅在组件挂载时执行一次。datasetDatauseEffect[]

服务器端数据获取

Next.js 提供了两个函数 `fetch()`getStaticPropsgetServerSideProps`fetch()`,用于在渲染过程中进行服务器端数据获取。这些函数允许你从 API 或数据库获取数据,并将其作为 props 传递给页面组件。

export async function getStaticProps() {
  const response = await fetch("https://api.example.com/data");
  const data = await response.json();

  return {
    props: {
      data,
    },
  };
}

function MyPage({ data }) {
  return (
    <div>
      {/* Display the fetched data */}
      {data && <p>{data.message}</p>}
    </div>
  );
}

export default MyPage;
Enter fullscreen mode Exit fullscreen mode

在上面的代码片段中,我们定义了一个getStaticProps函数,这是一个 Next.js 识别的用于预渲染的特殊函数。在函数内部getStaticProps,我们从 API 获取数据并将其作为dataprop 返回。MyPage组件接收到获取的数据后,会进行相应的渲染。

需要注意的是,`sty`getStaticProps用于静态生成,即在构建时预渲染页面内容;而 `sty`getServerSideProps用于每次请求时进行服务器端渲染。您可以根据具体用例选择合适的函数。Next.js
还提供了其他数据获取选项,例如getInitialProps用于兼容旧版或更高级场景。这些选项可以根据应用程序的需求灵活处理数据获取。

Next.js 通过将数据获取无缝集成到渲染管道中,简化了数据获取过程。无论您需要在客户端还是在服务器端渲染期间获取数据,Next.js 都提供了必要的工具,使数据获取高效便捷。


面向专业 Web 开发人员的开源企业应用平台

refine.new使您能够在浏览器中创建基于 React 的无头 UI 企业应用程序,您可以立即预览、调整和下载这些应用程序。

🚀 通过可视化组合您偏好的✨ React 平台、✨ UI 框架、✨ 后端连接器和✨ 身份验证提供程序,您可以在几秒钟内为您的项目创建量身定制的架构。这就像拥有触手可及的数千个项目模板,让您可以自由选择最符合您需求的模板!

优化博客徽标

Next.js 中的服务器操作

服务器端操作是 Web 应用程序不可或缺的一部分,它允许您处理服务器端逻辑并执行数据操作、身份验证等操作。Next.js 提供了一项名为 API 路由的强大功能,使您能够创建自定义服务器端点来无缝处理服务器端操作。接下来,我们将通过代码示例探讨如何在 Next.js 中使用 API 路由来实现服务器端操作。

创建 API 路由:

要在 Next.js 中创建 API 路由,需要在根pages/api目录下创建一个文件。该文件应根据所需的端点命名,例如 `.api.route` pages/api/users.js。在该文件中,您可以定义服务器端的操作逻辑。

// pages/api/users.js

export default function handler(req, res) {
  // Perform server action
  const myUsers = [
    { id: 1, name: "Odioko" },
    { id: 2, name: "Victor" },
  ];

  // Return the response
  res.status(200).json(myUsers);
}
Enter fullscreen mode Exit fullscreen mode

在上面的代码片段中,我们users.jspages/api目录中创建了一个 API 路由。在该handler函数中,我们执行所需的服务器操作,例如检索用户列表。在本例中,我们定义了一个简单的用户数组,并使用 `.getUsers()` 方法将其作为响应返回res.status(200).json(users)

使用服务器操作进行服务器端通信

Next.js 引入了服务器端操作(Server Actions)这一特性,目前仍处于 alpha 测试阶段。该特性基于 React Actions构建。借助这些操作,可以在服务器端发起数据更改,从而减少客户端 JavaScript 代码量,并实现可随时间推移而不断完善的表单。

如果你想在 Next 项目中添加服务器操作,请进入你的next.config.js文件并启用实验性serverActions标志。

module.exports = {
  experimental: {
    serverActions: true,
  },
};
Enter fullscreen mode Exit fullscreen mode

完成此操作后,您必须通过"use server"在组件函数体的顶部使用指令定义异步函数来创建服务器操作。

async function myServerAction() {
  "use server";
  // code here
}
Enter fullscreen mode Exit fullscreen mode

让我们来看一段文档中的代码,并解释一下它的作用。

import { cookies as nextCookies } from "next/headers";

export default function ProductCard({ productId }) {
  async function addToCart(data) {
    "use server";

    const cartId = nextCookies().get("cartId")?.value;
    await saveToDatabase({ cartId, data });
  }

  return (
    <form onSubmit={addToCart}>
      <button type="submit">Add to Cart</button>
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

上面的代码是 Next.js 中的一个 React 函数式组件,名为 ` <form> AddToCart`。它负责渲染一个带有Add to Cart按钮的表单。让我们来分析一下这段代码,了解它的功能。

  1. 该组件作为默认导出项导出,这意味着它可以被导入并在其他文件中使用。
  2. 该组件接收一个productIdprop,该 prop 可能代表卡片上显示的产品的 ID。此 prop 可用于获取相关的产品信息或执行任何必要的操作。
  3. addToCart函数是组件内部声明的一个异步函数。它会在表单提交时(即点击“添加到购物车”按钮时)触发。该函数可以访问一个data参数,该参数可以在调用时传递给它。
  4. 函数内部addToCart有一行注释"use server';。这条注释很可能表明接下来的代码应该只在服务器端执行,而不是在客户端运行。如果您正在使用 Next.js 并希望区分服务器端和客户端代码的执行,这一点就非常重要。
  5. 这段代码使用模块中的函数nextCookies().get('cartId')?.value检索 cookie 的值运算符用于可选链式调用,确保在 cookie 或其值不存在时代码不会抛出错误。cartIdnextCookiesnext/headers?.
  6. 这段代码表示将数据及其附件await saveToDatabase({ cartId, data })保存到数据库的异步任务。您需要将其替换为实际处理数据库保存逻辑的函数。datacartIdsaveToDatabase
  7. 该组件返回一个表单元素,其onSubmit事件处理程序设置为指定addToCart函数。这意味着当表单提交时(例如,点击“添加到购物车”按钮),该addToCart函数将被执行。
  8. 表单内只有一个按钮,点击该按钮Add to Cart即可触发表单提交。

如何调用服务器操作

在使用 Next.js 和服务器端操作时,有多种方法可以调用这些操作。让我们详细了解一下这些方法:

使用 action 属性:React 的 action 属性可以用来对表单元素调用服务器端操作,如下面的代码片段所示:

export default function TodoApp() {
  async function addTodoItem(data) {
    "use server";

    const todoId = getTodoId().get("todoId")?.value;
    await saveToDb({ todoId, data });
  }

  return (
    <form onSubmit={addTodoItem}>
      <button type="submit">Add Todo</button>
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

上面的代码片段TodoApp展示了一个简单的待办事项应用。用户可以通过提交表单来添加新的待办事项。addTodoItem表单提交后触发的函数会执行与添加待办事项相关的服务器端操作。它使用一个getTodoId函数检索待办事项 ID,并使用另一个函数将待办事项保存到数据库中saveToDb。这段代码为待办事项应用提供了一个基本结构,允许用户通过服务器端处理来添加待办事项。

使用 formAction prop<button> :在我们的 Next.js 代码中,我们可以使用prop 来处理元素上的表单操作,formAction如下面的代码所示:

export default function Form() {
  async function Submit() {
    "use server";
    // ...
  }

  async function submitFile() {
    "use server";
    // ...
  }

  return (
    <form action={Submit}>
      <input type="text" name="name" />
      <input type="image" formAction={submitFile} />
      <button type="submit">Submit</button>
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

在上面的例子中,Submit表单提交时会调用该函数,而submitFile点击文件输入框时会调用另一个函数。服务器端的操作由该属性触发formAction

startTransition 自定义调用:除了上面列出的两种调用服务器操作的方式之外,还有另一种方法可以执行服务器操作。这种方法使用startTransitionReact useTransitionHook 提供的 `this`,我们可以在不执行表单服务器操作时使用这种方法。

import { useTransition } from "react";
import { addTodo } from "../actions";

function TodoAppClientComponent({ id }) {
  const [isPending, startTransition] = useTransition();

  return (
    <button onClick={() => startTransition(() => addTodo(id))}>Add Todo</button>
  );
}
Enter fullscreen mode Exit fullscreen mode

上面的代码中,该startTransition函数封装了服务器操作的调用addTodo。当按钮被点击时,服务器操作就会执行。使用该函数startTransition可以控制服务器操作调用的时机。

客户端与 API 路由的通信

Next.js 使得客户端代码与 API 路由的通信变得无缝衔接。您可以使用fetchAPI 或任何其他 HTTP 库向 API 端点发出请求。

import { useEffect, useState } from "react";

function MyComponent() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    const fetchUsers = async () => {
      const response = await fetch("/api/users");
      const data = await response.json();
      setUsers(data);
    };

    fetchUsers();
  }, []);

  return (
    <div>
      {users.map((user) => (
        <p key={user.id}>{user.name}</p>
      ))}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

在上面的代码中,我们定义了一个组件,该组件使用APIMyComponent从端点获取用户数据。获取到的数据通过函数存储在状态变量中。我们使用带有空依赖数组的钩子来确保数据获取仅在组件挂载时执行一次。/api/usersfetchuserssetUsersuseEffect[]

请注意,从客户端代码向 API 路由发出请求时,可以使用相对 URL,/api/users因为 Next.js 会自动将请求路由到相应的 API 路由。Next.js
API 路由提供了一种强大的机制,可以在应用程序中无缝处理服务器操作。无论您需要获取数据、执行数据修改还是处理身份验证,API 路由都能让您轻松定义自定义服务器端点。

结论

我们探索了 Next.js 的基础知识、简化的安装流程及其优势。我们深入研究了数据获取,并通过代码示例展示了客户端和服务端技术。此外,我们还探讨了使用 Next.js API 路由实现服务器操作的概念,从而能够创建自定义服务器端点来处理服务器端逻辑和操作。

Next.js 不断发展演进,助力开发者构建能够提供卓越用户体验的 Web 应用。通过充分利用 Next.js 的数据获取和服务器端操作功能,开发者可以释放现代 Web 开发的真正潜力,始终走在瞬息万变的 Web 开发领域的前沿。现在就开启您的 Next.js 之旅,探索其强大的功能,将您的 Web 开发项目提升到新的高度吧!

文章来源:https://dev.to/refine/nextjs-134s-server-actions-and-data-fetching-n3m