next-data-hooks终极指南:如何在Next.js中将getStaticProps转换为React Hooks
2026/7/21 20:15:04 网站建设 项目流程

next-data-hooks终极指南:如何在Next.js中将getStaticProps转换为React Hooks

【免费下载链接】next-data-hooksUse `getStaticProps`/`getServerSideProps` as react-hooks项目地址: https://gitcode.com/gh_mirrors/ne/next-data-hooks

next-data-hooks是一个轻量级库,它能让你在Next.js中像使用React Hooks一样使用getStaticPropsgetServerSideProps,通过将静态属性提升到React Context中,实现更优雅的数据获取方式。

为什么需要next-data-hooks?

在传统的Next.js开发中,我们通常在页面组件中编写大型的数据查询函数,这导致代码组织不够清晰。而next-data-hooks带来了以下优势:

  1. 更好的代码组织:像Apollo、Relay和React Query等异步数据获取框架一样,让你可以在组件附近编写数据查询,使代码结构更清晰。

  2. TypeScript友好:导入数据钩子时,同时也导入了其返回类型,在组件中调用钩子时,类型已经存在,提供更好的类型支持。

⚠️ 注意:它没有提供比原生Next.js更多的功能,主要优势在于提供了一种组织getStaticProps/getServerSideProps的模式。

快速开始:安装与配置

安装依赖

首先,通过npm或yarn安装next-data-hooks:

npm i next-data-hooks

或者

yarn add next-data-hooks

添加Babel插件

在项目根目录添加.babelrc文件,包含以下内容:

{ "presets": ["next/babel"], "plugins": ["next-data-hooks/babel"] }

⚠️ 不要忘记这一步。这启用了代码消除功能,以消除客户端代码中的服务器端代码。

配置_app.tsx

_app.tsx_app.js中添加提供程序:

import { AppProps } from 'next/app'; import { NextDataHooksProvider } from 'next-data-hooks'; function App({ Component, pageProps }: AppProps) { const { children, ...rest } = pageProps; return ( <NextDataHooksProvider {...rest}> <Component {...rest}>{children}</Component> </NextDataHooksProvider> ); }

核心功能:创建和使用数据钩子

创建数据钩子

你可以在组件所在的文件或其他任何地方创建数据钩子:

import { createDataHook } from 'next-data-hooks'; // 这里的context是来自'next'的GetStaticPropsContext // 👇 const useBlogPost = createDataHook('BlogPost', async (context) => { const slug = context.params?.slug as string; // 执行异步操作获取组件所需的数据 const blogPost = /* ... */; return blogPost; }); export default useBlogPost;
TypeScript用户注意事项

如果你计划仅在getServerSideProps上下文中使用数据钩子,可以导入提供的类型守卫isServerSidePropsContext来缩小传入上下文的类型:

import { createDataHook, isServerSidePropsContext } from 'next-data-hooks'; const useServerSideData = createDataHook('Data', async (context) => { if (!isServerSidePropsContext(context)) { throw new Error('This data hook only works in getServerSideProps.'); } // 在这里,`context`的类型已被缩小为服务器端上下文 const query = context.req.query; }); export default useServerSideData;

在组件中使用数据钩子

在组件中使用数据钩子,并将其添加到静态属性的数组中,与其他数据钩子组合:

import ComponentThatUsesDataHooks from '..'; import useBlogPost from '..'; import useOtherDataHook from '..'; function BlogPostComponent() { const { title, content } = useBlogPost(); const { other, data } = useOtherDataHook(); return ( <article> <h1>{title}</h1> <p>{content}</p> <p> {other} {data} </p> </article> ); } // 组合其他数据钩子 BlogPostComponent.dataHooks = [ ...ComponentThatUsesDataHooks.dataHooks, useOtherDataHooks, useBlogPost, ]; export default BlogPostComponent;

在getStaticProps或getServerSideProps中传递数据钩子

import { getDataHooksProps } from 'next-data-hooks'; import { GetStaticPaths, GetStaticProps } from 'next'; import BlogPostComponent from '..'; export const getStaticPaths: GetStaticPaths = async (context) => { // 返回静态路径... }; // 注意:这也适用于`getServerSideProps` export const getStaticProps: GetStaticProps = async (context) => { const dataHooksProps = await getDataHooksProps({ context, // 这是来自`dataHooks`静态属性的所有数据钩子的数组。 // 👇👇👇 dataHooks: BlogPostComponent.dataHooks, }); return { props: { // 展开next-data-hooks所需的属性 ...dataHooksProps, // 在此处添加其他属性到Next.js }, }; }; export default BlogPostComponent;

实用模式:优化项目结构

单独的routes目录

Next.js有一个非常固执的基于文件的路由机制,不允许在/pages文件夹中放置文件而不将其视为页面。这限制了代码的组织方式。

使用next-data-hooks,你可以将/pages文件夹视为入口点文件夹,并在其他地方组织文件:

my-project # 将pages文件夹视为路由的入口点 ├── pages │ ├── blog │ │ ├── [slug].ts │ │ └── index.ts │ └── shop │ ├── category │ │ └── [slug].ts │ ├── index.ts │ └── product │ └── [slug].ts || # 将每个路由文件夹视为自己的应用,拥有自己的组件和助手 └── routes ├── blog │ ├── components │ │ ├── blog-index.tsx │ │ ├── blog-post-card.tsx │ │ └── blog-post.tsx │ └── helpers │ └── example-blog-helper.ts └── shop ├── components │ ├── category.tsx │ ├── product-description.tsx │ └── product.tsx └── helpers └── example-shop-helper.ts
/routes/blog/components/blog-post.tsx
import { createDataHook } from 'next-data-hooks'; // 在共存的位置编写数据钩子 const useBlogPostData = createDataHook('BlogPost', async (context) => { const blogPostData = // 获取博客文章数据… return blogPostData; }); function BlogPost() { // 在组件中使用它 const { title, content } = useBlogPostData(); return ( <article> <h1>{title}</h1> <p>{content}</p> </article> ); } BlogPost.dataHooks = [useBlogPostData]; export default BlogPost;
/pages/blog/[slug].ts
import { GetStaticProps, GetStaticPaths } from 'next'; import { getDataHooksProps } from 'next-data-hooks'; import BlogPost from 'routes/blog/components/blog-post'; export const getStaticPaths: GetStaticPaths = {}; /* ... */ export const getStaticProps: GetStaticProps = async (context) => { const dataHooksProps = getDataHooksProps({ context, dataHooks: BlogPost.dataHooks, }); return { props: dataHooksProps }; }; // 重新导出组件。此文件只是一个入口点 export default BlogPost;

👋 注意:以上只是如何使用next-data-hooks组织项目的示例。主要收获是你可以重新导出页面组件来更改结构,而next-data-hooks与此模式配合良好。

组合数据钩子

每个数据钩子都公开一个getData方法,该方法就是你传递给createDataHook的函数。

这可以在其他数据钩子中使用以拉取相同的数据:

import { createDataHook } from 'next-data-hooks'; const useHook = createDataHook('DataHook', async (context) => { return; // ... }); export default useHook;
import useHook from './'; const useOtherHook = createDataHook('Other', async (context) => { const data = await useHook.getData(context); // 使用数据做一些事情… });

👋 注意:请注意,此方法会重新运行该函数。

代码消除

为了减小捆绑包大小,Next.js会消除仅用于getStaticProps内部的代码。

next-data-hooks通过一个babel插件实现了同样的功能,该插件在数据钩子定义前加上typeof window !== 'undefined' ? <stub> : <real data hook>

这是因为Next.js在浏览器中将表达式typeof window预评估为'object'。这将使上面的三元表达式在浏览器中始终评估为<stub>。Terser然后会将<real data hook>表达式从浏览器捆绑包中消除。

如果你看到错误Create data hook was run in the browser.,则代码消除可能出现问题。请打开一个issue。

👋 注意:Next.js的默认代码消除和next-data-hooks的代码消除可能存在差异。请仔细检查你的捆绑包。

总结

next-data-hooks提供了一种将Next.js的数据获取方法(getStaticPropsgetServerSideProps)转换为React Hooks的优雅方式,使代码组织更加清晰,同时保持与Next.js的兼容性。通过本文介绍的安装配置、创建使用数据钩子以及实用模式,你可以快速上手并优化你的Next.js项目结构。

要开始使用next-data-hooks,只需克隆仓库:

git clone https://gitcode.com/gh_mirrors/ne/next-data-hooks

然后按照本文的指南进行配置和使用,体验更高效的Next.js数据获取方式!

【免费下载链接】next-data-hooksUse `getStaticProps`/`getServerSideProps` as react-hooks项目地址: https://gitcode.com/gh_mirrors/ne/next-data-hooks

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询