You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next 13中如何实现API获取的全局分类常量复用?

可行实现方案及替代思路

方案1:构建时预生成静态常量文件(推荐,无环境差异)

如果分类数据不会频繁更新,直接在构建阶段拉取API数据生成静态常量文件,后续所有代码直接导入使用即可,彻底避免服务端/客户端环境差异问题。

  1. 编写Node脚本拉取分类数据并生成常量文件:
// scripts/fetch-categories.js
const fs = require('fs');
const fetch = require('node-fetch');

async function generateCategoryConstants() {
  // 调用外部API获取分类数据
  const res = await fetch('https://your-api-domain/categories');
  const categories = await res.json();
  
  // 转成可直接导入的JS常量格式
  const constantContent = `export const CATEGORIES = ${JSON.stringify(categories, null, 2)};`;
  // 写入项目目录,比如utils文件夹下
  fs.writeFileSync('./app/utils/category-constants.js', constantContent);
}

generateCategoryConstants();
  1. 在package.json的构建脚本前添加预执行命令,确保每次构建前自动拉取最新分类:
{
  "scripts": {
    "prebuild": "node scripts/fetch-categories.js",
    "build": "next build",
    // 其他脚本...
  }
}
  1. 全局复用:在普通JS文件、SSR/客户端组件里直接导入即可:
import { CATEGORIES } from '@/app/utils/category-constants';

// 示例判断逻辑
if (product.categoryId === CATEGORIES.DRINKS.id) {
  // 处理饮品分类产品
}

方案2:运行时全局缓存+Context传递(适合动态更新场景)

如果分类数据需要在运行时动态获取(比如构建后可能更新),通过全局缓存确保仅请求一次,再结合React Context让客户端组件便捷访问。

  1. 创建全局缓存模块:
// app/utils/category-cache.js
let cachedCategories = null;

export async function getCategories() {
  // 缓存存在则直接返回,避免重复请求
  if (cachedCategories) return cachedCategories;
  
  const res = await fetch('https://your-api-domain/categories', {
    // 开启Next.js缓存,服务端客户端共享缓存
    cache: 'force-cache'
  });
  cachedCategories = await res.json();
  return cachedCategories;
}
  1. 根布局(Server Component)预取数据并注入Context:
// app/layout.js
import { createContext, useContext } from 'react';
import { getCategories } from '@/app/utils/category-cache';

const CategoriesContext = createContext(null);

export async function RootLayout({ children }) {
  // 服务端预取分类数据,仅执行一次
  const categories = await getCategories();
  
  return (
    <html lang="zh-CN">
      <body>
        <CategoriesContext.Provider value={categories}>
          {children}
        </CategoriesContext.Provider>
      </body>
    </html>
  );
}

// 封装自定义Hook供客户端组件使用
export function useCategories() {
  const context = useContext(CategoriesContext);
  if (!context) throw new Error('useCategories必须在CategoriesContext.Provider范围内使用');
  return context;
}
  1. 全局复用方式:
  • 服务端组件/普通JS文件:直接调用getCategories()(缓存自动生效)
  • 客户端组件:使用useCategories() Hook获取数据

方案3:结合RTK Query缓存(适配已有RTK的项目)

如果项目已经使用Redux Toolkit,直接利用RTK Query的缓存机制管理分类数据,确保全局仅请求一次。

  1. 创建分类API切片:
// app/store/api/categoriesApi.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const categoriesApi = createApi({
  reducerPath: 'categoriesApi',
  baseQuery: fetchBaseQuery({ baseUrl: 'https://your-api-domain/' }),
  endpoints: (builder) => ({
    getCategories: builder.query({
      query: () => 'categories',
      // 设置永久缓存,避免重复请求
      keepUnusedDataFor: Infinity
    })
  })
});

// 客户端组件用Hook
export const { useGetCategoriesQuery } = categoriesApi;

// 非组件环境(普通JS/服务端)获取缓存数据的方法
export async function getCategoriesFromCache(store) {
  const state = store.getState();
  const cachedData = categoriesApi.endpoints.getCategories.select()(state);
  
  if (cachedData.data) return cachedData.data;
  // 缓存不存在则发起请求并等待结果
  const result = await store.dispatch(categoriesApi.endpoints.getCategories.initiate());
  return result.data;
}
  1. 全局复用方式:
  • 客户端组件:使用useGetCategoriesQuery()获取数据
  • 服务端组件/普通JS文件:通过Redux Store调用getCategoriesFromCache()获取缓存数据

内容的提问来源于stack exchange,提问作者user24751344

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 22:07:28