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

