Next.js 作为 React 的一个超火框架,最大的亮点之一就是它的服务端渲染(SSR)和静态站点生成(SSG)能力。而要玩转这两种能力,getStaticProps 和 getServerSideProps 是绕不过去的核心函数。这篇文章就来聊聊这两个函数的来龙去脉,从技术背景到实现原理,再到实际应用,尽量用大白话讲清楚,让你看完就能上手!
技术背景:Next.js 为什么需要这两个函数?
咱们先来聊聊 Next.js 的“初心”。React 本身是个前端框架,擅长做单页应用(SPA),但 SPA 有个问题:首次加载全靠客户端渲染,SEO 不友好,首屏加载也可能慢。Next.js 横空出世,解决了这个问题,它既能做静态站点生成(SSG),让页面提前渲染好,又能做服务端渲染(SSR),让服务器动态生成页面。这俩功能让 Next.js 在性能、SEO 和用户体验上都占了上风。
但问题来了:怎么控制页面到底是静态生成还是动态渲染?Next.js 给出的答案就是 getStaticProps 和 getServerSideProps。这两个函数就像是 Next.js 的“超级管家”,帮你决定页面数据怎么来、什么时候渲染,彻底解放你的双手。
名词解释:getStaticProps 和 getServerSideProps 是啥?
getStaticProps
简单来说,getStaticProps 是在构建时(build time)跑的函数。Next.js 会在你执行 next build 的时候调用它,把数据抓过来,生成静态的 HTML 文件。用户访问页面时,直接把这些预渲染好的 HTML 甩过去,速度快到飞起,SEO 也友好。
- 特点:数据在构建时就确定,适合内容不怎么变动的页面,比如博客文章、产品文档。
- 使用场景:你想让页面加载快、SEO 好,而且数据不需要实时更新。
- 限制:构建后数据就固定了,如果数据变了,得重新构建。
getServerSideProps
getServerSideProps 就不同了,它是在每次请求时跑的。用户访问页面,服务器临时去抓数据,渲染好 HTML 再返回给浏览器。适合那些数据实时性要求高的场景,比如用户仪表盘、实时库存。
- 特点:动态渲染,服务器每次都会重新生成页面。
- 使用场景:数据经常变,或者需要根据用户请求动态生成内容。
- 限制:服务器压力大,响应时间可能比静态页面慢。
实现原理:它们是怎么干活的?
getStaticProps 的工作流程
- 构建时执行:你在代码里定义了
getStaticProps,Next.js 会在next build时运行它。 - 数据获取:这个函数可以调用 API、查数据库、读文件,反正就是把你需要的数据准备好。
- 生成静态页面:Next.js 把数据塞到你的页面组件里,生成静态的 HTML 和 JSON 文件,存在服务器上。
- 用户请求:用户访问页面时,服务器直接把预生成的 HTML 返回,浏览器再“激活” React 组件(hydration)。
- 增量静态再生(ISR) :如果用了 ISR,Next.js 还能在后台定期更新静态页面,简直是“静态”和“动态”的完美结合。
getServerSideProps 的工作流程
- 请求时执行:用户每次访问页面,Next.js 都会跑一遍
getServerSideProps。 - 动态获取数据:跟
getStaticProps类似,可以调用 API 或数据库,但这次是实时跑的。 - 服务器渲染:Next.js 在服务器上把数据和页面组件合在一起,生成 HTML。
- 返回给浏览器:浏览器拿到 HTML,显示页面,再完成 React 的 hydration。
技术细节
- 环境:
getStaticProps只在构建时跑,getServerSideProps在服务器跑,两者都不能直接访问浏览器专属的 API(比如window)。 - 返回格式:两个函数都得返回一个对象,包含
props(传给页面的数据),getStaticProps还能返回revalidate(用于 ISR)。 - 性能对比:
getStaticProps依赖构建时的静态文件,速度快;getServerSideProps每次请求都要服务器干活,速度慢一点。
应用实例:怎么用这两个函数?
好了,讲了这么多理论,咱们来点实际的!下面是两个简单的例子,分别用 getStaticProps 和 getServerSideProps 实现一个博客列表页面。
示例 1:用 getStaticProps 做博客列表(静态生成)
假设你有个博客网站,文章数据存在 CMS 里,内容不常变,适合用 getStaticProps。
// pages/index.js
import Link from 'next/link';
export async function getStaticProps() {
// 模拟从 CMS 获取文章列表
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
return {
props: {
posts, // 把数据传给页面组件
},
revalidate: 60, // 每60秒更新一次(ISR)
};
}
export default function Blog({ posts }) {
return (
<div>
<h1>我的博客</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link href={`/posts/${post.id}`}>
{post.title}
</Link>
</li>
))}
</ul>
</div>
);
}
解释:
getStaticProps在构建时从 API 拉取文章数据。- 数据通过
props传给Blog组件,页面渲染成静态 HTML。 revalidate: 60开启了 ISR,页面每分钟更新一次,保持内容新鲜。
示例 2:用 getServerSideProps 做用户仪表盘(动态渲染)
假设你有个用户仪表盘,显示用户的实时数据,比如最近的订单信息。
// pages/dashboard.js
export async function getServerSideProps(context) {
// 从请求中获取用户 ID(假设通过认证)
const userId = context.req.session.userId;
// 模拟从数据库获取用户订单
const res = await fetch(`https://api.example.com/orders?userId=${userId}`);
const orders = await res.json();
return {
props: {
orders,
},
};
}
export default function Dashboard({ orders }) {
return (
<div>
<h1>你的订单</h1>
<ul>
{orders.map((order) => (
<li key={order.id}>
订单 #{order.id} - {order.status}
</li>
))}
</ul>
</div>
);
}
解释:
getServerSideProps在每次请求时运行,根据用户 ID 拉取订单数据。- 数据通过
props传给Dashboard组件,服务器动态生成 HTML。 - 适合实时性要求高的场景,比如用户仪表盘。
怎么选?getStaticProps vs getServerSideProps
选哪个函数,取决于你的场景:
- 用 getStaticProps:如果你的页面内容不常变,比如博客、文档、电商的产品页面,优先选它。速度快、SEO 好,还能用 ISR 实现动态更新。
- 用 getServerSideProps:如果页面内容强依赖用户请求,比如用户专属数据、实时库存,选它更合适。
- 混合使用:Next.js 很灵活,一个项目里可以用
getStaticProps做静态页面,也可以用getServerSideProps做动态页面。
小 tips 和注意事项
- 别在客户端跑:这两个函数只能在页面(
pages/目录)里用,不能在组件里用。 - 优化性能:
getStaticProps配合 CDN 能极大提升速度;getServerSideProps要小心服务器负载,尽量缓存数据。 - 错误处理:记得在函数里加
try-catch,避免 API 挂了导致页面崩掉。 - 调试技巧:用
console.log在getStaticProps里看数据,日志会出现在构建时的终端;getServerSideProps的日志在服务器终端。
总结:Next.js 的渲染利器
getStaticProps 和 getServerSideProps 是 Next.js 的两大法宝,一个主打静态生成,一个专注动态渲染。它们让 Next.js 在性能、SEO 和灵活性上找到完美平衡。希望这篇文章能让你对这两个函数有更深的理解,下次写 Next.js 项目时,选对它们,事半功倍!
有啥问题,欢迎随时交流,咱们继续聊 Next.js 的骚操作!