这里发生的事情是我想通过 getStaticPaths
结合 getStaticProps
来使用 Next.js 的 SSG。在开发中一切正常。但是当我运行构建命令时,它会抛出这样的错误:
在 /mentor/[id] 的 getStaticPaths 中没有以字符串形式提供必需的参数 (id)
我的文件夹结构如下:
|- pages
|- api
|- mentors
|- [id].ts
|- index.ts
|- mentor
|- [id].tsx
|- _app.tsx
|- _document.tsx
|- index.tsx
我的导师 API 如下所示:
pages/api/mentors/index.ts
import { mentors } from "utils/dummyDatas";
import { NextApiRequest, NextApiResponse } from "next";
export default (req: NextApiRequest, res: NextApiResponse) => {
res.status(200).json(mentors);
};
我的导师/:id API 看起来像这样:
pages/api/mentors/[id].ts
import { mentors } from "utils/dummyDatas";
import { NextApiRequest, NextApiResponse } from "next";
export default (req: NextApiRequest, res: NextApiResponse) => {
const { id } = req.query;
const selectedMentor = mentors.find((mentor) => mentor.id.toString() === id);
res.status(200).json(selectedMentor);
};
dummyDatas 看起来像这样:
utils/dummyDatas.ts
export const mentors: MentorType[] = [
{
id: 1,
name: "John Doe",
description:
"Lorem ipsum, dolor sit amet consectetur adipisicing elit. Rerum quidem earum perferendis, facilis quos vero, nobis maxime explicabo quo adipisci modi a ducimus? Dicta labore delectus consequatur sint, nisi temporibus.",
image:
"https://images.unsplash.com/photo-1539571696357-5a69c17a67c6?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80",
},
...
]
现在有了所有这些资源,我想尝试 SSG,这是我实现 SSG 的代码。
pages/mentor/[id].tsx
import axios from "axios";
import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from "next";
// Components
import { MentorDetail } from "containers";
import { MentorType } from "utils/types";
import { Header } from "molecules";
interface IProps {
mentor: MentorType;
}
function Detail({ mentor }: IProps) {
return (
<>
<Header loggedIn={false} />
<MentorDetail mentor={mentor} />
</>
);
}
export const getStaticPaths: GetStaticPaths = async () => {
try {
const { data } = await axios.get("http://localhost:3000/api/mentors");
const paths = data.map((mentor: MentorType) => {
return {
params: { id: mentor.id.toString() },
};
});
return {
paths,
fallback: false,
};
} catch {
return { paths: [{}], fallback: false };
}
};
export const getStaticProps: GetStaticProps = async (
context: GetStaticPropsContext
) => {
try {
const { data } = await axios.get(
`http://localhost:3000/api/mentors/${context.params.id}`
);
return {
props: {
mentor: data,
},
};
} catch {
return {
props: {},
};
}
};
export default Detail;
答案 0 :(得分:0)
这个问题很可能是因为在构建时您的请求失败了,因此 catch
块返回一个空的 paths
数组。
您不应使用 axios
在 getStaticProps
/getStaticPaths
中调用内部 API 路由。来自 Next.js 文档:
您不应使用 fetch()
(或在本例中为 axios
)来调用 getStaticProps 中的 API 路由。相反,直接导入 API 路由中使用的逻辑。您可能需要为这种方法稍微重构您的代码。
从外部 API 获取没问题!
您需要稍微重构 API 路由代码以导出其逻辑。
// pages/api/mentors/[id].ts
import { mentors } from "utils/dummyDatas";
import { NextApiRequest, NextApiResponse } from "next";
export const getMentorById = (id: string) => mentors.find((mentor) => mentor.id.toString() === id);
export default (req: NextApiRequest, res: NextApiResponse) => {
const { id } = req.query;
const selectedMentor = getMentorById(id);
res.status(200).json(selectedMentor);
};
然后在您的 getStaticPaths
中,您需要直接导入 mentors
数据。
// pages/mentor/[id].tsx
import { mentors } from "<path-to>/utils/dummyDatas"; // Replace with your actual path to the file
export const getStaticPaths: GetStaticPaths = async () => {
const paths = mentors.map((mentor: MentorType) => {
return {
params: { id: mentor.id.toString() }
};
};
return {
paths,
fallback: false
};
};
在您的 getStaticProps
中,您需要重用 API 路由中定义的 getMentorById
函数,而不是发出请求。
// pages/mentor/[id].tsx
import { getMentorById } from "<path-to>/api/mentors/[id]" // Replace with your actual path to the file
export const getStaticProps: GetStaticProps = async (context: GetStaticPropsContext) => {
const data = getMentorById(context.params.id);
return {
props: {
mentor: data
}
};
};