搜索
首页web前端js教程使用 NextJS 掌握 CRUD

Mastering CRUD with NextJS

在 Web 开发中,CRUD 操作是基本构建块,对于管理数据至关重要。它们几乎在每个应用程序中无处不在,从简单的网站到复杂的企业解决方案。

NestJS Boilerplate 用户已经能够评估和使用功能强大的新工具 - CLI,它允许您自动创建资源及其属性。使用此工具,您可以进行所有 CRUD 操作并向其中添加必要的字段,而无需手动编写一行代码。同时,正如我们一再宣布的,BC Boilerplates 生态系统包括一个完全兼容的 Extective-React-Boilerplate,以提供完整的功能(原则上,它可以是一个完全独立的解决方案)。现在让我们从前端角度探讨一下 CRUD 操作。

在具有服务器端渲染功能的 React 框架 Next.js 中,可以通过增强性能、SEO 和开发人员体验的功能来有效管理这些操作。之前,我们发表了一篇关于启动 NextJS 项目的有效方法的文章,现在我们想进一步分析使用 Next.js 中的 API 的细节和细微差别。

众所周知,CRUD 缩写代表创建、读取、更新和删除。这个概念代表了可以对任何数据执行的基本操作。让我们考虑使用管理面板用户的示例来处理 CRUD 操作,其中实现了添加、编辑和删除用户等功能,以及检索有关用户的信息。下面讨论的自定义 React 钩子,用于处理 React Query 中的数据处理、分页、错误管理等,已经集成到 Extective-React-Boilerplate 中。当然,您可以直接利用这个样板。在以下部分中,我们将分享我们对实现这些功能的见解。

创建操作

用例:提交数据以创建新资源(例如,用户注册、添加新产品)。
实现: 从表单收集数据,向服务器发送 POST 请求,处理响应,并相应地更新 UI。

让我们观察一个例子。向 API 发出 POST 请求会合并创建新用户。在下面的代码片段中,usePostUserService 钩子用于封装此逻辑。我们已经通过定义请求和响应类型来指定创建新用户的数据结构,但这里省略这一部分以帮助您集中注意力。您可以在存储库 Extective-React-Boilerplate 中查看更详细的信息或更完整的图片,因为此代码片段以及以下所有代码片段都来自那里。
因此,我们将创建一个自定义挂钩 usePostUserService,它使用 useFetch 挂钩发送 POST 请求。它将用户数据作为输入并将其发送到 API:

function usePostUserService() {
  const fetch = useFetch();
  return useCallback(
    (data: UserPostRequest, requestConfig?: RequestConfigType) => {
      return fetch(`${API_URL}/v1/users`, {
        method: "POST",
        body: JSON.stringify(data),
        ...requestConfig,
      }).then(wrapperFetchJsonResponse<userpostresponse>);
    },
    [fetch]
  );
}

</userpostresponse>

函数wrapperFetchJsonResponse 将在本文稍后讨论“错误处理”时进行研究。

读操作

用例:获取并显示资源列表或单个资源(例如,获取用户配置文件和产品列表)。
实现:发送 GET 请求来获取数据,处理加载和错误状态,并在 UI 中呈现数据。

在我们的示例中,读取数据涉及向 API 发出 GET 请求以获取用户数据。它可以包括使用分页、过滤器获取所有用户,以及在定义请求 (UsersRequest) 和响应类型 (UsersResponse) 后按 ID 排序或获取单个用户。
要在自定义 useGetUsersService 挂钩中获取所有用户,我们发送带有用于分页、过滤器和排序的查询参数的 GET 请求:

function useGetUsersService() {
  const fetch = useFetch();

  return useCallback(
    (data: UsersRequest, requestConfig?: RequestConfigType) => {
      const requestUrl = new URL(`${API_URL}/v1/users`);
      requestUrl.searchParams.append("page", data.page.toString());
      requestUrl.searchParams.append("limit", data.limit.toString());
      if (data.filters) {
        requestUrl.searchParams.append("filters", JSON.stringify(data.filters));
      }
      if (data.sort) {
        requestUrl.searchParams.append("sort", JSON.stringify(data.sort));
      }

      return fetch(requestUrl, {
        method: "GET",
        ...requestConfig,
      }).then(wrapperFetchJsonResponse<usersresponse>);
    },
    [fetch]
  );
}
</usersresponse>

用于获取单个用户 useGetUserService 挂钩发送 GET 请求以按 ID 获取用户:

function useGetUserService() {
  const fetch = useFetch();
  return useCallback(
    (data: UserRequest, requestConfig?: RequestConfigType) => {
      return fetch(`${API_URL}/v1/users/${data.id}`, {
        method: "GET",
        ...requestConfig,
      }).then(wrapperFetchJsonResponse<userresponse>);
    },
    [fetch]
  );
}
</userresponse>

更新操作

用例:编辑现有资源(例如,更新用户信息、编辑博客文章)。
实现:收集更新的数据,向服务器发送 PUT 或 PATCH 请求,处理响应,并更新 UI。

让我们更新现有用户,这涉及到使用更新的用户数据向 API 发送 PATCH 请求。为此,在自定义 usePatchUserService 挂钩中,我们在定义请求 UserPatchRequest 和响应类型 UserPatchResponse 后发送带有用户 ID 和更新数据的 PATCH 请求:

function usePatchUserService() {
  const fetch = useFetch();
  return useCallback(
    (data: UserPatchRequest, requestConfig?: RequestConfigType) => {
      return fetch(`${API_URL}/v1/users/${data.id}`, {
        method: "PATCH",
        body: JSON.stringify(data.data),
        ...requestConfig,
      }).then(wrapperFetchJsonResponse<userpatchresponse>);
    },
    [fetch]
  );
}
</userpatchresponse>

注意:对于部分数据更新,使用 PATCH 代替 PUT 更为高级,而 PUT 通常用于完整资源更新。

删除操作

用例:删除资源(例如,删除用户或从列表中删除项目)。
实现: 向服务器发送 DELETE 请求,处理响应,并更新 UI 以反映删除。

在我们的下一个示例中,删除用户涉及使用用户 ID 向您的 API 发送 DELETE 请求。在 useDeleteUsersService 挂钩中定义请求 (UsersDeleteRequest) 和响应类型 (UsersDeleteResponse) 后,将传输 DELETE 请求以通过 ID 删除用户。

function usePostUserService() {
  const fetch = useFetch();
  return useCallback(
    (data: UserPostRequest, requestConfig?: RequestConfigType) => {
      return fetch(`${API_URL}/v1/users`, {
        method: "POST",
        body: JSON.stringify(data),
        ...requestConfig,
      }).then(wrapperFetchJsonResponse<userpostresponse>);
    },
    [fetch]
  );
}

</userpostresponse>

这些钩子抽象了发出 HTTP 请求和处理响应的复杂性,使用这种方法可确保干净且可维护的代码库,因为数据获取逻辑被封装并可在组件之间重用。

在 Next.js 中检索数据

好了,我们已经介绍了处理CRUD操作的例子,下面我们来仔细看看Next.js提供的获取数据的方法,因为它作为一个框架,在React的基础上增加了它的功能和优化。很明显,Next.js 除了 CSR(客户端渲染)之外,还提供了高级功能,如 SSR(服务器端渲染)、SSG(静态站点生成)、内置 API 路由和混合渲染。那么,让我们讨论一下 Next.js 和 React 中检索数据的共性和差异。

只要 React 应用程序是纯粹的客户端,那么数据获取就会在初始页面加载后发生在客户端上。对于每次加载页面时都需要获取数据的动态页面,

更适合使用SSR,在这种情况下,数据是在请求时在服务器上获取的。 对于 SSG,它适用于数据不经常更改的静态页面,数据是在构建时获取的。因此,getStaticProps 方法可以帮助我们
在构建时获取数据 (SSG)。如果我们需要基于动态路由和构建时获取的数据来预渲染页面,则 getStaticPaths 方法允许执行此操作。它与 getStaticProps 结合使用在构建时生成动态路由。需要注意的是,从 Next 14 开始,我们可以直接在组件中发出请求,而无需这些方法,从而提供了更多“React 体验”。

使用 useQuery 进行客户端数据获取可用于需要在客户端获取数据的交互式组件,其初始状态是从服务器端获取的数据中获取的。对于获取频繁更改的数据或添加客户端交互性,useSWR 策略非常有用。它是一个用于客户端数据获取、缓存和重新验证的 React 钩子。它允许在客户端获取数据,通常是在初始页面加载之后。尽管如此,它不会在构建时或在 SSR 服务器上获取数据,但它可以在需要时重新验证并获取新数据。

为了总结有关上述方法的信息,我们可以看一下表格,该表格全面概述了 Next.js 中的不同数据获取方法,突出显示了它们各自的时间和用例。

Method Data Fetching Timing Use Case
getStaticPaths Static Site Generation (SSG) At build time Pre-render pages for dynamic routes based on data available at build time.
getStaticProps Static Site Generation (SSG) At build time Pre-render pages with static content at build time. Ideal for content that doesn't change frequently.
getServerSideProps Server-Side Rendering (SSR) On each request Fetch data on the server for each request, providing up-to-date content. Ideal for dynamic content that changes frequently.
useQuery Client-Side Rendering (CSR) After the initial page load Fetch initial data server-side, hydrate, reduce redundant network requests, Background Refetching.
useSWR Client-Side Rendering (CSR) After the initial page load Fetch and revalidate data on the client-side, suitable for frequently changing data.

将 React Query 与 Next.js 结合使用

React Query 提供了用于获取、缓存、同步和更新服务器状态的钩子,使其成为处理 React 和 Next.js 应用程序中数据的绝佳工具。使用它的主要好处是:

  • 高效的数据获取:它处理缓存和后台数据同步,减少冗余的网络请求。
  • 自动重新获取:数据过时时可以在后台自动重新获取,确保UI始终显示最新信息。
  • 集成错误处理:内置对处理错误和重试的支持,使管理网络故障和服务器错误变得更加容易。
  • 乐观更新: useMutation 钩子通过提供一种简单的方法来处理乐观 UI 更改和服务器请求失败时的回滚逻辑,从而提供乐观更新。
  • 易于与 Next.js 集成:它可以与 getStaticProps 或 getServerSideProps(如果需要)等其他 Next.js 数据获取方法无缝集成。
  • 检查查询和突变:ReactQueryDevtools 工具提供了查看所有活动查询和突变的状态、数据、错误和其他详细信息的可能性,并在应用程序运行时实时观察查询状态更新.

查询客户端提供者

QueryClientProvider 是一个上下文提供者组件,它向 React 组件树提供 QueryClient 实例。这个实例对于使用像 useQuery 这样的钩子是必需的。 要进行设置,需要将其放置在组件树的根部,并为查询和突变配置全局设置,例如重试行为、缓存时间等。之后,它会初始化 React Query 客户端并使其在整个应用程序中可用。

function usePostUserService() {
  const fetch = useFetch();
  return useCallback(
    (data: UserPostRequest, requestConfig?: RequestConfigType) => {
      return fetch(`${API_URL}/v1/users`, {
        method: "POST",
        body: JSON.stringify(data),
        ...requestConfig,
      }).then(wrapperFetchJsonResponse<userpostresponse>);
    },
    [fetch]
  );
}

</userpostresponse>

那么,为什么要把它添加到项目中呢?它有益于:

  • 所有查询和突变的集中配置。
  • 易于设置并集成到现有的 React 应用程序中。
  • 启用缓存、后台重新获取和查询失效等功能。

React 查询开发工具

React Query 提供的另一个重要功能是 React Query Devtools - 一个用于检查和调试 React Query 状态的开发工具。它可以轻松添加到您的应用程序中,并通过浏览器扩展或作为组件进行访问,如前面的示例所示。
在开发过程中,React Query Devtools 可用于检查单个查询和突变,了解为什么某些查询会预取并监视查询缓存的状态,并查看它如何随着时间的推移而演变。

分页和无限滚动

要使用库中的功能实现分页控件或无限滚动,useInfiniteQuery 是完美的选择。首先,我们生成唯一的键,用于在 React Query 中缓存和检索查询。这里的 by 方法根据排序和过滤选项创建唯一键。

function usePostUserService() {
  const fetch = useFetch();
  return useCallback(
    (data: UserPostRequest, requestConfig?: RequestConfigType) => {
      return fetch(`${API_URL}/v1/users`, {
        method: "POST",
        body: JSON.stringify(data),
        ...requestConfig,
      }).then(wrapperFetchJsonResponse<userpostresponse>);
    },
    [fetch]
  );
}

</userpostresponse>

为此,我们将使用 React Query 中的 useInfiniteQuery 函数,并采用上面读取操作部分中讨论的 useGetUsersService 挂钩。

function useGetUsersService() {
  const fetch = useFetch();

  return useCallback(
    (data: UsersRequest, requestConfig?: RequestConfigType) => {
      const requestUrl = new URL(`${API_URL}/v1/users`);
      requestUrl.searchParams.append("page", data.page.toString());
      requestUrl.searchParams.append("limit", data.limit.toString());
      if (data.filters) {
        requestUrl.searchParams.append("filters", JSON.stringify(data.filters));
      }
      if (data.sort) {
        requestUrl.searchParams.append("sort", JSON.stringify(data.sort));
      }

      return fetch(requestUrl, {
        method: "GET",
        ...requestConfig,
      }).then(wrapperFetchJsonResponse<usersresponse>);
    },
    [fetch]
  );
}
</usersresponse>

这里的 QueryFn 根据当前页面、过滤器和排序参数检索用户数据,而 getNextPageParam 函数根据上一页的响应确定要获取的下一页。当用户滚动或请求更多数据时,useInfiniteQuery 会根据 nextPage 参数自动检索下一组数据 - 这就是无限滚动发生的方式。查询的缓存时间由 gcTime 参数设置。

总的来说,React Query 提供了一个用于管理和调试 React 应用程序中服务器状态的全面解决方案。 QueryClientProvider 确保所有查询和突变的集中且一致的配置,而 ReactQueryDevtools 提供强大的工具用于在开发过程中检查和理解查询行为。

错误处理

实现 CRUD 操作始终需要适当的错误处理,以确保用户友好性和应用程序可靠性。服务器错误通常与客户端请求处理失败、服务器代码错误、资源过载、基础设施配置错误或外部服务故障相关。对于错误处理,Extective-react-boilerplate 建议使用wrapperFetchJsonResponse 函数:

function useGetUserService() {
  const fetch = useFetch();
  return useCallback(
    (data: UserRequest, requestConfig?: RequestConfigType) => {
      return fetch(`${API_URL}/v1/users/${data.id}`, {
        method: "GET",
        ...requestConfig,
      }).then(wrapperFetchJsonResponse<userresponse>);
    },
    [fetch]
  );
}
</userresponse>

结论

在本文中,我们介绍了基本的 CRUD 操作,探索了 NextJS 中的数据检索技术。我们深入研究了使用 React Query 来管理状态,还概述了 QueryClientProvider 和 ReactQueryDevtools 用于调试和优化数据检索的功能。此外,我们还讨论了如何实现分页和无限滚动来处理大型数据集,并解决了错误处理问题,使您的应用程序更具弹性并确保流畅的用户体验。

通过遵循本文中概述的示例和技术,您现在应该能够在 NextJS 项目中处理 CRUD 操作。或者,您可以为您的项目使用我们的 Extective-react-boilerplate 模板。它具有完全兼容的 Nestjs-boilerplate 后端,可以在几分钟内实现使用 CRUD 操作的能力,而无需使用 CLI 编写一行代码,我们已在此处和此处针对实体关系更详细地介绍了这一点。不断尝试,随时了解最佳实践,如果您发现它有用,欢迎尝试此样板。

我们的 BC Boilerplates 团队始终在寻找加强开发的方法。我们很想听听您对 GitHub 讨论或下面评论的想法。

本文全部归功于 Olena Vlasenko 和 Vlad Shchepotin ??

以上是使用 NextJS 掌握 CRUD的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
Python vs. JavaScript:开发人员的比较分析Python vs. JavaScript:开发人员的比较分析May 09, 2025 am 12:22 AM

Python和JavaScript的主要区别在于类型系统和应用场景。1.Python使用动态类型,适合科学计算和数据分析。2.JavaScript采用弱类型,广泛用于前端和全栈开发。两者在异步编程和性能优化上各有优势,选择时应根据项目需求决定。

Python vs. JavaScript:选择合适的工具Python vs. JavaScript:选择合适的工具May 08, 2025 am 12:10 AM

选择Python还是JavaScript取决于项目类型:1)数据科学和自动化任务选择Python;2)前端和全栈开发选择JavaScript。Python因其在数据处理和自动化方面的强大库而备受青睐,而JavaScript则因其在网页交互和全栈开发中的优势而不可或缺。

Python和JavaScript:了解每个的优势Python和JavaScript:了解每个的优势May 06, 2025 am 12:15 AM

Python和JavaScript各有优势,选择取决于项目需求和个人偏好。1.Python易学,语法简洁,适用于数据科学和后端开发,但执行速度较慢。2.JavaScript在前端开发中无处不在,异步编程能力强,Node.js使其适用于全栈开发,但语法可能复杂且易出错。

JavaScript的核心:它是在C还是C上构建的?JavaScript的核心:它是在C还是C上构建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; saninterpretedlanguagethatrunsonenginesoftenwritteninc.1)javascriptwasdesignedAsalightweight,解释edganguageforwebbrowsers.2)Enginesevolvedfromsimpleterterterpretpreterterterpretertestojitcompilerers,典型地提示。

JavaScript应用程序:从前端到后端JavaScript应用程序:从前端到后端May 04, 2025 am 12:12 AM

JavaScript可用于前端和后端开发。前端通过DOM操作增强用户体验,后端通过Node.js处理服务器任务。1.前端示例:改变网页文本内容。2.后端示例:创建Node.js服务器。

Python vs. JavaScript:您应该学到哪种语言?Python vs. JavaScript:您应该学到哪种语言?May 03, 2025 am 12:10 AM

选择Python还是JavaScript应基于职业发展、学习曲线和生态系统:1)职业发展:Python适合数据科学和后端开发,JavaScript适合前端和全栈开发。2)学习曲线:Python语法简洁,适合初学者;JavaScript语法灵活。3)生态系统:Python有丰富的科学计算库,JavaScript有强大的前端框架。

JavaScript框架:为现代网络开发提供动力JavaScript框架:为现代网络开发提供动力May 02, 2025 am 12:04 AM

JavaScript框架的强大之处在于简化开发、提升用户体验和应用性能。选择框架时应考虑:1.项目规模和复杂度,2.团队经验,3.生态系统和社区支持。

JavaScript,C和浏览器之间的关系JavaScript,C和浏览器之间的关系May 01, 2025 am 12:06 AM

引言我知道你可能会觉得奇怪,JavaScript、C 和浏览器之间到底有什么关系?它们之间看似毫无关联,但实际上,它们在现代网络开发中扮演着非常重要的角色。今天我们就来深入探讨一下这三者之间的紧密联系。通过这篇文章,你将了解到JavaScript如何在浏览器中运行,C 在浏览器引擎中的作用,以及它们如何共同推动网页的渲染和交互。JavaScript与浏览器的关系我们都知道,JavaScript是前端开发的核心语言,它直接在浏览器中运行,让网页变得生动有趣。你是否曾经想过,为什么JavaScr

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器