Next.js 13变化有多大?

Next.js 13+ 推出的 App Router 是一次重大架构升级,彻底改变了数据获取的方式。

它最大的特点是拥抱了 Web 标准 ,不再需要 getStaticPropsgetServerSideProps 这两个专属函数,而是直接使用 React 核心特性 (如 async/await 组件、use 钩子)来实现数据获取。使用NEXT 写起来越来越"像"React

一、核心变化:从"生命周期"到"组件形态"

在 App Router 中,页面(Page)和布局(Layout)本身就是 Async 组件 ,可以直接在组件顶层 await 获取数据,逻辑更直观。

特性 Pages Router (旧) App Router (新)
数据获取方式 专属 API:getStaticProps / getServerSideProps 直接 async/await (组件内)
运行环境 函数运行时 组件所在的渲染边界 (服务端/客户端)
代码位置 必须导出单独的函数 与组件代码写在一起
核心思维 基于路由的"文件系统" + 数据函数 基于组件树的 React 服务器组件

二、App Router 里怎么替代?

1. 替代 getStaticProps (静态生成)

在旧方案中,我们用它来在构建时生成静态页面。
新方案:直接在组件顶层 await,并开启缓存。

jsx 复制代码
// app/posts/page.js (App Router 页面)
import PostList from './PostList'

// 这是一个 Server Component (默认就是),可以直接 async
export default async function PostsPage() {
  // 直接在组件里请求数据
  // 默认情况下,fetch 会被自动缓存 (等同于 getStaticProps)
  const res = await fetch('https://api.example.com/posts')
  const posts = await res.json()

  return <PostList posts={posts} />
}
2. 替代 getServerSideProps (服务端渲染)

在旧方案中,我们用它来每次请求都获取最新数据。
新方案:使用 fetch 并配置 cache: 'no-store'

jsx 复制代码
// app/dashboard/page.js
export default async function DashboardPage() {
  // 添加 no-store,每次访问都会重新请求 (等同于 getServerSideProps)
  const res = await fetch('https://api.example.com/user-data', {
    cache: 'no-store'
  })
  const userData = await res.json()

  return <DashboardContent data={userData} />
}
3. 替代 revalidate (增量静态再生 ISR)

旧方案用 revalidate: 10 来定时更新,新方案更灵活。

jsx 复制代码
// app/blog/page.js
export default async function BlogPage() {
  // 后台每 60 秒重新验证并更新数据
  const res = await fetch('https://api.example.com/blog-posts', {
    next: { revalidate: 60 }
  })
  const posts = await res.json()

  return <BlogList posts={posts} />
}

三、客户端组件怎么获取数据?

如果是需要在浏览器运行、或依赖用户交互的客户端组件(带 'use client'),不能直接 await,需使用 React 的 use 钩子

jsx 复制代码
'use client'
import { use } from 'react'

export default function ClientPost({ promise }) {
  // use 可以直接 resolve 一个 Promise
  const post = use(promise)
  
  return <div>{post.title}</div>
}

// 在父页面调用
import ClientPost from './ClientPost'
export default function Page() {
  // 父组件是 Server Component,可以直接 async
  const fetchPost = async () => {
    const res = await fetch('...')
    return res.json()
  }

  // 把 Promise 传给客户端组件
  return <ClientPost promise={fetchPost()} />
}

三、SSG动态路由有什么变化?

在 Next.js 13+ App Router 里,getStaticPaths 被一个新函数替代了:

✨ 新名字:generateStaticParams

它的作用完全等同于旧的 getStaticPaths ,专门用来处理动态路由 (比如 /posts/[id]/product/[slug]),告诉 Next.js:
构建时要提前生成哪些页面?

旧版 Pages Router:getStaticPaths
js 复制代码
// pages/posts/[id].js
export async function getStaticPaths() {
  return {
    paths: [
      { params: { id: '1' } },
      { params: { id: '2' } },
    ],
    fallback: 'blocking' // 重要
  };
}
新版 App Router:generateStaticParams
js 复制代码
// app/posts/[id]/page.js
// 直接导出这个函数就行
export async function generateStaticParams() {
  // 这里返回要预先生成的所有 id
  return [
    { id: '1' },
    { id: '2' },
  ];
}
区别:
  • 不用写 pathsparams
  • 不用写 fallback
  • 默认就是 fallback: blocking(最常用、最安全的模式)

完整可复制示例

这是 App Router 动态路由 + 静态生成的标准写法

jsx 复制代码
// app/posts/[id]/page.js

// 1. 告诉 Next.js 构建时生成哪些页面
export async function generateStaticParams() {
  // 你可以在这里请求接口获取所有文章ID
  // const res = await fetch('https://api.example.com/posts')
  // const posts = await res.json()

  // 返回要预先生成的参数列表
  return [
    { id: '1' },
    { id: '2' },
    { id: '3' },
  ];
}

// 2. 页面组件(默认 async 服务端组件)
export default async function PostPage({ params }) {
  const { id } = params;

  // 自动缓存 = 相当于 getStaticProps
  const res = await fetch(`https://api.example.com/posts/${id}`);
  const post = await res.json();

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  );
}

旧版 Pages Router 新版 App Router 作用
getStaticProps 直接 async await fetch 构建时获取数据
getStaticPaths generateStaticParams 动态路由预生成页面
revalidate fetch(..., { next: { revalidate: 60 } }) 定时刷新

总结

App Router 的核心思想是 "服务器组件"

  1. 默认就是服务端,能直接读写文件、调接口、连数据库,无需特殊 API。
  2. fetch 自带缓存 ,通过 cachenext.revalidate 配置,完美覆盖了 SSG、SSR、ISR 所有场景。
  3. 代码更集中,逻辑更清晰,完全符合 React 的未来发展方向。
相关推荐
糖炒栗子03262 小时前
前端项目标准环境搭建与启动
前端
不是az2 小时前
CSS知识点记录
前端·javascript·css
爱分享的阿Q2 小时前
GPT6-Spud-AGI前夜的豪赌
前端·easyui·agi
西西小飞龙2 小时前
Less/Sass Mixins vs. Extend
前端·less·sass
syjy22 小时前
(含下载)BeTheme WordPress主题使用教程
前端·wordpress·wordpress建站
Misnice3 小时前
shadcn如何使用
前端·reactjs
h_jQuery3 小时前
vue使用gm-crypto对数据进行sm4加密处理
前端·javascript·vue.js
阿赛工作室3 小时前
Vue中onBeforeUnmount不触发的解决方案
前端·javascript·vue.js
码王吴彦祖3 小时前
顶象 AC 纯算法迁移实战:从补环境到纯算的完整拆解
java·前端·算法