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

Next.js+TypeScript中如何复用services目录下的数据获取函数

问题原因

Next.js 对 getStaticProps、getServerSideProps、getStaticPaths 这类路由级数据获取函数有固定解析逻辑:框架只会扫描pages目录下的页面文件,识别文件内直接导出的特殊函数,不会识别仅导入、未在页面文件内显式导出的同名函数。
你当前的写法只是把外部定义的getStaticProps导入到了页面文件,没有将其作为页面自身的导出项,Next.js在构建/渲染页面时根本检测不到数据获取逻辑,不会执行这段请求代码,传给Home组件的data值为undefined,调用.map自然会抛出类型错误。
另外要明确:你要拆分到services文件夹的应该是纯数据请求逻辑,而不是Next.js专属的路由钩子本身,钩子是和页面路由强绑定的,本身就应该定义在页面文件内。

正确写法
  1. 先改造services/getUserRepos.ts,只保留通用请求逻辑,去掉Next.js钩子专属的返回结构:
// services/getUserRepos.ts
export async function fetchUserRepos() {
  const response = await fetch(
    `https://api.github.com/users/abdurrahmanseyidoglu/repos`
  );
  return response.json();
}
  1. 在页面文件pages/index.tsx内定义并导出getStaticProps,钩子内部调用拆分好的service方法,按Next.js要求返回props结构:
// pages/index.tsx
import { fetchUserRepos } from "../services/getUserRepos";

const Home = ({ data }) => {
  return (
    <>
      <ul>
        {data.map((repo) => (
          <li key={repo.id}>{repo.name}</li>
        ))}
      </ul>
      <p className="max-w-5xl m-auto text-justify mt-2 border rounded p-3 shadow-lg">
        正常运行示例
      </p>
    </>
  );
};

// 必须在页面文件内直接导出,Next.js才能识别到这个钩子
export async function getStaticProps() {
  const data = await fetchUserRepos();

  if (!data) {
    return {
      notFound: true,
    };
  }

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

export default Home;
补充说明
  • 不推荐把完整的getStaticProps逻辑抽到外部文件,就算你在外部写好后在页面里用export { getStaticProps } from 'xxx'重新导出能跑,也会让路由和数据逻辑的绑定关系变模糊,后续维护成本更高。
  • 可以给组件props加兜底逻辑避免偶发报错,比如把data.map改成data?.map,或者给data设置默认空数组初始值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:48:16