第 3 章:数据获取方法(数据渲染)
Next.js 支持三种主要的服务端数据获取方式,可以根据页面的需求选择合适的渲染策略:
- 静态生成(SSG)
- 服务端渲染(SSR)
- 增量静态生成(ISR)
此外,客户端还可以使用 useSWR 或 fetch 发起 API 请求。
3.1 getStaticProps(静态生成 SSG)
用于构建时生成静态页面,内容不会实时变化,适合内容固定的页面(如博客首页、文档页)。
用法:
export async function getStaticProps() {
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
return {
props: { posts }, // 会传入页面组件作为 props
};
}
export default function Home({ posts }) {
return (
<ul>
{posts.map((p) => (
<li key={p.id}>{p.title}</li>
))}
</ul>
);
}
特点:
- 仅在构建阶段运行(
next build) - 适合展示型、低更新频率页面
- 页面响应速度极快
3.2 getServerSideProps(服务端渲染 SSR)
每次请求都会在服务端生成页面,适合需要动态展示实时数据的页面(如用户中心、搜索结果等)。
用法:
export async function getServerSideProps(context) {
const res = await fetch('https://api.example.com/user');
const user = await res.json();
return {
props: { user }, // 页面渲染时注入
};
}
export default function Profile({ user }) {
return <h1>欢迎回来,{user.name}</h1>;
}
特点:
- 每次请求都会运行
- 数据总是最新
- 会影响加载速度(受网络、API 响应影响)
3.3 getStaticPaths(配合动态路由使用)
当页面使用了动态路由(如 [id].js),需要生成多个静态页面时,需要 getStaticPaths。
export async function getStaticPaths() {
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
const paths = posts.map((post) => ({
params: { id: post.id.toString() }, // 路径参数
}));
return {
paths,
fallback: false, // 未包含的路径会返回 404
};
}
配合使用 getStaticProps(context):
export async function getStaticProps({ params }) {
const res = await fetch(`https://api.example.com/posts/${params.id}`);
const post = await res.json();
return { props: { post } };
}
3.4 ISR(增量静态生成)
在静态生成的基础上,Next.js 提供了增量更新机制:设置 revalidate,可在后台定时更新静态页面。
export async function getStaticProps() {
const data = await fetchData();
return {
props: { data },
revalidate: 10, // 10 秒自动重新生成一次页面(后台)
};
}
ISR 特点:
- 兼具性能和动态性
- 不影响用户访问速度
- 推荐用于新闻、价格等更新频率不高但需要定时刷新的内容
3.5 客户端数据获取:useSWR 或 fetch
用于组件挂载后,在浏览器中请求数据,适合用户私有数据、实时数据、点击加载更多等需求。
示例:使用 SWR
npm install swr
import useSWR from 'swr';
const fetcher = (url) => fetch(url).then((res) => res.json());
export default function Profile() {
const { data, error } = useSWR('/api/user', fetcher);
if (error) return <div>加载失败</div>;
if (!data) return <div>加载中...</div>;
return <div>欢迎回来,{data.name}</div>;
}
✅ 三种方式对比总结:
| 特性 | getStaticProps | getServerSideProps | useSWR |
|---|---|---|---|
| 渲染时机 | 构建时 | 请求时 | 客户端运行时 |
| 是否预渲染 | ✅ 是 | ✅ 是 | ❌ 否 |
| 支持 SEO | ✅ 是 | ✅ 是 | ❌ 否 |
| 数据是否实时 | ❌ 否(可配 ISR) | ✅ 是 | ✅ 是 |
| 场景示例 | 博客文章、文档 | 用户页、订单页 | 聊天消息、天气 |
小结
- 若数据不常变,使用 SSG (
getStaticProps) ; - 若必须实时、登录敏感,使用 SSR (
getServerSideProps) ; - 若是客户端行为(点击、用户登录后加载),用
useSWR; - 若页面是动态路径,配合
getStaticPaths; - 若页面要定期更新但不实时,使用 ISR (
revalidate) 。