将 getStaticPaths 与动态路由一起使用
Posted
技术标签:
【中文标题】将 getStaticPaths 与动态路由一起使用【英文标题】:Usage of getStaticPaths with dynamic routes 【发布时间】:2021-09-19 23:17:45 【问题描述】:我有一个索引页面,我按部分(热门电影、热门电影等)显示电影,为此我在 getStaticProps
中调用 不同 api url。现在在[movieId].js
页面中,我使用的是getStaticPaths
,因为我使用的是动态路由。但我不明白的是用户可以点击 any 部分上的 any 电影项目,但因为我需要在[movideId].js
中获取所有可能电影的路径页面并在getStaticPaths
中以paths
返回,
我如何知道用户点击了哪个部分,以便我可以在 getStaticPaths
中调用该特定 api 以获取正确的数据并返回正确的路径?
这是我的代码
// index.js
export default function Home(props)
return (
<>
<div>
<h1>Trending</h1>
props.trending.results.map((movie, index) =>
return (
<div key=index>
<Link href=`/movie/$movie.id`>
<a>movie.original_title</a>
</Link>
</div>
);
)
</div>
<div>
<h1>Popular</h1>
props.popular.results.map((movie, index) =>
return (
<div key=index>
<Link href=`/movie/$movie.id`>
<a>movie.original_title</a>
</Link>
</div>
);
)
</div>
</>
);
export async function getStaticProps()
try
const token = '...';
const [trendingRes, popularRes] = await Promise.all([
fetch(
`https://api.themoviedb.org/3/trending/movie/week?api_key=$token`
),
fetch(
`https://api.themoviedb.org/3/movie/popular?api_key=$token&language=en-US&page=1`
)
]);
const [trending, popular] = await Promise.all([
trendingRes.json(),
popularRes.json()
]);
return props: trending, popular ;
catch (err)
return notFound: true ;
// [movieId].js
export async function getStaticPaths()
const token = "...";
const res = await fetch(
`https://api.themoviedb.org/3/trending/movie/week?api_key=$token` // here I am hardcoding to call trending api url no matter which section a user has clicked on
);
const data = await res.json();
return
paths: data.results.map((d) => ( params: movieId: d.id.toString() ))
;
Full Code sample
现在如果用户点击popular
部分的电影,它会显示 404 not found 页面,因为我只有来自趋势 api url 的数据和路径。
我还在学习 nextjs,所以希望我的解释可以理解,请随意询问有关此的更多详细信息。
【问题讨论】:
【参考方案1】:在现实生活中,如果您拥有大型数据集,您不会希望预渲染所有可能的组合和所有可能的电影页面。
幸运的是,getStaticPaths
有一个 fallback
标志。
你可以使用fallback: blocking
(docs),这样如果页面的key没有在getStaticPaths
中指定,页面将在第一次请求后生成(并缓存)。但是您需要一个 api,您可以在其中按 id 获取电影。你有它,所以你需要做的就是改变fallback
键。 Check this Stackblitz example
如果您没有这样的 api,您可以例如拆分您的路线并拥有 /trending/[id]
路线和 popular/[id]
路线。这样您就可以始终知道需要从哪里获取电影。
希望它有意义,请随时提出其他问题。
【讨论】:
您提到if you have large data set you would not want to prerender all the possible combinations and all possible movie pages.
,这是否意味着最好按照您的建议拆分路线并使用不同的路线以获得更好的实践?
不,我的意思是,如果你有 10 万部电影,那么你不想在构建时制作 10 万个预渲染页面,那将是愚蠢的。
哦,我明白了。谢谢,我会记住这一点的。【参考方案2】:
鉴于您提到的示例,我不会使用getStaticPaths
,而是使用getServerSideProps
,因为getStaticPaths
用例仅适用于您想要静态生成少量页面的情况。
在getServerSideProps
中,您将可以访问context
对象。然后,访问context.query
将获得您页面的动态路径包含的任何内容。
举个例子:
在 Next.js 项目的 pages
文件夹中,创建一个名为 movies
的文件夹,然后在其中创建一个 [id].js
。
这将匹配以下路径:
/movies/1
/movies/123
/movies/456
然后您可以使用动态路径(即123
)调用您的 API 并获取特定电影。
【讨论】:
以上是关于将 getStaticPaths 与动态路由一起使用的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Next.js 中设置多语言环境动态页面的 getStaticPaths
Next.js 动态路由错误:提供的路径 `page-name` 与页面不匹配:`/[slug]`
错误:动态 SSG 页面需要 getStaticPaths,而“xxx”缺少 getStaticPaths。 NextJS
是否可以使用 API 路由在 Next.JS getStaticProps/getStaticPaths 中构建页面? [复制]