Next.js动态路由中为何使用getStaticProps时需搭配getStaticPaths()
两种写法的构建逻辑差异决定了是否需要声明预渲染路径:
无getStaticProps的动态路由场景
对应代码如下:
// [id].js function Id() { return <h1>Hello World</h1> } export default Id
执行npm run build构建时,Next.js只会生成一份通用的[id].html模板。因为这个页面的渲染内容和路由参数完全无关,不管用户访问的是/123还是/abc,返回的都是完全相同的Hello World内容,框架不需要提前知道有多少个合法的动态路由值,靠通用模板就能匹配所有符合规则的路径,自然不需要额外配置路径列表。
带getStaticProps的动态路由场景
对应代码如下:
// [id].js function Id(props) { const { test } = props return <h1>{test.foo}</h1> } export default Id
一旦页面导出了getStaticProps,就等于告知Next.js:这个页面需要在构建阶段完成数据拉取,为每个合法路由预渲染出独立的静态HTML文件。
这时候getStaticProps的执行强依赖路由参数:不同的id会拉取到不同的业务数据,最终渲染出的页面内容完全不同,没有办法用一份通用模板覆盖所有路径。构建是离线执行的流程,Next.js不可能自动枚举所有可能的参数取值——毕竟这些id、slug是和业务数据绑定的,框架不可能知道你站点下有多少篇文章、多少个商品,对应的合法参数是什么。
这时候就必须通过getStaticPaths显式返回所有需要预渲染的路由参数列表,构建阶段才能逐个把参数传入getStaticProps拉取对应数据,生成每个路径专属的静态HTML文件。
直白点说:印统一内容的宣传单,你不需要给印刷厂列所有发传单的地点,印完通用版本去哪发都行;但如果要印带不同收件人信息的定制快递单,你必须先把所有收件人地址、姓名给印刷厂,人家根本没法自己猜你要寄给谁。
额外提一句:如果动态路由用的是getServerSideProps做服务端渲染,也不需要getStaticPaths——因为这种模式是用户发起请求时才在服务端拉数据渲染页面,不需要构建期提前生成静态文件,自然不用提前枚举路由。
内容的提问来源于stack exchange,提问作者Stautenberg

