Next.js 14 App Router 完全指南:服务端组件、流式渲染与中间件实战


一、前言:Next.js 14 是现代全栈 React 开发的标配

Next.js 14 的 App Router 是自 React 16 以来最重要的架构升级。RSC(React Server Components)、Streaming SSR、Middleware 三大特性,让前后端边界彻底重构,开发体验和用户体验双双提升。


二、App Router 架构解析

2.1 服务端组件 vs 客户端组件

tsx 复制代码
// app/dashboard/page.tsx
// 默认是服务端组件(Server Component)
// 可以直接 await 数据库查询,无需 API Routes
async function DashboardPage() {
  const user = await db.user.findUnique({
    where: { id: params.userId }
  });

  return (
    <div>
      <h1>欢迎回来,{user.name}</h1>
      <OrderList orders={orders} />
    </div>
  );
}

2.2 客户端组件(需要交互时)

tsx 复制代码
// components/LikeButton.tsx
'use client';  // 必须声明

import { useState } from 'react';

export function LikeButton({ initialCount }: { initialCount: number }) {
  const [count, setCount] = useState(initialCount);
  return <button onClick={() => setCount(c => c + 1)}>👍 {count}</button>;
}

2.3 服务端组件调用客户端组件

tsx 复制代码
// 服务端获取数据,客户端组件负责交互
async function PostPage({ params }) {
  const post = await getPost(params.id);
  return (
    <article>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
      <LikeButton initialCount={post.likes} />
    </article>
  );
}

三、Streaming 流式渲染

3.1 Suspense + 骨架屏

tsx 复制代码
async function DashboardPage() {
  return (
    <div>
      <UserStats />
      <Suspense fallback={<OrdersSkeleton />}>
        <RecentOrders />
      </Suspense>
      <Suspense fallback={<ChartSkeleton />}>
        <AnalyticsChart />
      </Suspense>
    </div>
  );
}

function OrdersSkeleton() {
  return (
    <div className="animate-pulse space-y-2">
      {[1,2,3].map(i => (
        <div key={i} className="h-12 bg-gray-200 rounded" />
      ))}
    </div>
  );
}

四、Middleware 中间件

4.1 认证守卫

tsx 复制代码
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const token = request.cookies.get('auth_token');

  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  const response = NextResponse.next();
  response.headers.set('X-Custom-Header', 'Hello from Middleware');
  return response;
}

export const config = {
  matcher: ['/dashboard/:path*', '/profile/:path*']
};

4.2 A/B 测试中间件

tsx 复制代码
export function middleware(request: NextRequest) {
  const response = NextResponse.next();

  if (!request.cookies.has('ab_variant')) {
    const variant = Math.random() > 0.5 ? 'A' : 'B';
    response.cookies.set('ab_variant', variant, { maxAge: 60 * 60 * 24 * 30 });
  }

  return response;
}

五、数据请求与缓存

5.1 三种缓存策略

tsx 复制代码
// 静态数据(CDN缓存)
fetch('url', { cache: 'force-cache' });

// 动态数据(每次请求重新获取)
fetch('url', { cache: 'no-store' });

// ISR(每小时自动重新生成)
fetch('url', { next: { revalidate: 3600 } });

5.2 并行与顺序请求

tsx 复制代码
// 并行(推荐)
const [user, stats, orders] = await Promise.all([
  getUser(), getStats(), getOrders()
]);

// 顺序(有依赖关系)
const user = await getUser();
const posts = await getUserPosts(user.id);

💬 Next.js 14 App Router 是现代全栈 React 开发的标配。收藏本文,项目重构不再迷茫!

标签:nextjs | react | 前端 | ssr

相关推荐
Royzst9 小时前
图书管理案例
java·开发语言
Hello--_--World9 小时前
利用CDN进行首屏优化。能不能看CDN与本地服务器谁快用谁?
运维·服务器·前端·javascript·vite
我的世界洛天依9 小时前
胡桃讲编程 | 外挂的另一种方法与防御 —— 对象(JS ES262)
开发语言·javascript·ecmascript
执明wa9 小时前
从 T 到协变逆变
java·开发语言·数据结构
lianghyan9 小时前
List.stream().min
java·开发语言
Hello--_--World9 小时前
为什么 用vite进行分包后,可以通过 浏览器强制缓存 提高性能?路由懒加载进行的分包与 vite进行的分包有什么不同?
前端·javascript·缓存·vite
三*一9 小时前
Mapbox GL JS 前端多边形分割实战:从踩坑到优雅实现
开发语言·前端·javascript·vue.js
计算机安禾9 小时前
【c++面向对象编程】第37篇:面向对象设计原则(一):单一职责与开闭原则
开发语言·c++·开闭原则
小明同学0110 小时前
C++后端项目:统一大模型接入 SDK(三)
开发语言·c++
Brilliantwxx10 小时前
【C++】 继承与多态(下)
开发语言·c++