Next.js App Router如何实现类似getStaticProps的静态页面渲染?
我使用Next.js已有一段时间,现正通过App Router启动新项目(原传统路由方式称为Pages Router)。在Pages Router中,我可导出getStaticProps在构建时预渲染页面,这非常适合数据不常变动的场景(如作品集网站)。根据官方文档:
If you export a function called getStaticProps (Static Site Generation) from a page,
Next.js will pre-render this page at build time using the props returned by getStaticProps.
但在App Router的page.tsx文件中导出getStaticProps时,出现如下错误:
"getStaticProps" is not supported in app/.
Read more: https://nextjs.org/docs/app/building-your-application/data-fetching
查看错误提示的文档后我十分困惑,文档内容围绕缓存展开,而我需求的是生成静态页面。请问在新的App Router中能否实现该功能?若可以,具体该如何操作?
App Router完全支持构建时静态预渲染页面,只是实现方式和Pages Router不同,不再依赖getStaticProps这类专用函数,而是通过服务器组件异步数据获取+默认缓存策略来实现,以下是具体操作方法:
1. 基础静态页面生成(替代getStaticProps核心功能)
App Router中的page.tsx默认是服务器组件,你可以直接在组件内部编写异步函数获取数据,Next.js会在构建阶段自动执行这些数据请求,将页面预渲染为静态HTML,和getStaticProps的效果完全一致。
示例代码(作品集页面):
// app/portfolio/page.tsx // 异步获取数据函数 async function fetchPortfolioData() { // 可从本地文件、CMS或外部API获取数据 const response = await fetch('./data/portfolio-items.json'); return response.json(); } // 页面组件(异步函数) export default async function PortfolioPage() { const portfolioItems = await fetchPortfolioData(); return ( <div className="portfolio-container"> <h1>我的作品集</h1> <div className="items-grid"> {portfolioItems.map(item => ( <div key={item.id} className="portfolio-item"> <h3>{item.title}</h3> <p>{item.description}</p> </div> ))} </div> </div> ); }
这种方式下,Next.js在构建时会完成数据获取和页面渲染,生成静态文件,部署后无需服务器实时处理请求。
2. 显式指定静态缓存策略
如果你的数据来自外部API,默认的fetch缓存策略是force-cache(即构建时缓存数据),和getStaticProps行为一致。如果需要明确确保静态生成,可以显式设置:
const response = await fetch('https://your-cms-api.com/portfolio', { cache: 'force-cache' // 强制构建时缓存数据 });
3. 增量静态再生(对应getStaticProps的revalidate)
如果需要定期更新静态页面(类似getStaticProps中的revalidate参数),可以通过两种方式实现:
- 在fetch请求中设置:
const response = await fetch('https://your-cms-api.com/portfolio', { next: { revalidate: 86400 } // 24小时后自动重新生成页面 }); - 在路由段中全局设置:在
page.tsx或layout.tsx中导出revalidate变量,对整个路由段生效:// app/portfolio/page.tsx export const revalidate = 86400; // 整个作品集页面24小时更新一次 async function fetchPortfolioData() { /* ... */ } export default async function PortfolioPage() { /* ... */ }
核心逻辑说明
App Router采用了更简洁的数据获取模型:服务器组件允许直接在组件内异步获取数据,Next.js通过缓存策略控制数据获取的时机(构建时、请求时或定期更新)。getStaticProps的核心功能(构建时预渲染+静态缓存),通过默认的服务器组件数据获取+force-cache策略就能完全实现,无需额外的专用函数。
内容的提问来源于stack exchange,提问作者yoty66

