You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js如何在构建时静态渲染前3页,其余页面实时渲染?

在Next.js中实现指定分页页面预渲染+其余页面实时获取

要实现构建阶段预渲染前3页、其余页面实时加载的需求,核心是结合Next.js的静态生成(SSG)和客户端数据获取能力,具体步骤如下:

1. 创建动态路由页面

在pages目录下创建动态路由文件,比如pages/posts/[page].js,用来处理所有分页请求。

2. 配置getStaticPaths指定预渲染页面

通过getStaticPaths告诉Next.js构建时要预渲染哪些页面(这里是第1-3页),同时设置fallback: true,让未预渲染的页面能正常访问并在客户端动态加载数据:

export async function getStaticPaths() {
  // 生成前3页的路由参数
  const paths = Array.from({ length: 3 }, (_, i) => ({
    params: { page: (i + 1).toString() },
  }));

  // fallback: true 表示未在paths中的页面会交由客户端处理
  return { paths, fallback: true };
}

3. 用getStaticProps获取预渲染页面的数据

对getStaticPaths指定的页面,在getStaticProps中获取对应分页的数据并传递给组件:

export async function getStaticProps({ params }) {
  const page = parseInt(params.page);
  // 替换成你的实际数据接口
  const res = await fetch(`https://your-api.com/posts?page=${page}`);
  const data = await res.json();

  return {
    props: {
      posts: data.posts,
      currentPage: page,
      isPreRendered: true, // 标记当前页面是否为预渲染页面
    },
    // 可选:让预渲染页面定期自动更新(比如每60秒重新生成)
    // revalidate: 60,
  };
}

4. 组件内部处理实时加载逻辑

在组件中判断当前页面是否为预渲染页面(或直接判断页码是否大于3),如果是,则在客户端发起请求获取实时数据。这里推荐用SWR(Next.js官方推荐的数据获取库),它自带缓存和重新验证能力,体验更流畅:

先安装SWR:

npm install swr

组件代码示例:

import { useState, useEffect } from 'react';
import useSWR from 'swr';

const PostsPage = ({ posts: initialPosts, currentPage: initialPage, isPreRendered }) => {
  const [currentPage, setCurrentPage] = useState(initialPage);
  const [posts, setPosts] = useState(initialPosts);

  // 定义数据获取函数
  const fetcher = async (url) => {
    const res = await fetch(url);
    return res.json();
  };

  // 非预渲染页面(页码>3)用SWR实时拉取数据
  const { data, error } = useSWR(
    !isPreRendered ? `https://your-api.com/posts?page=${currentPage}` : null,
    fetcher
  );

  // 当SWR拿到新数据时更新页面状态
  useEffect(() => {
    if (data) {
      setPosts(data.posts);
    }
  }, [data]);

  // 分页切换逻辑
  const handlePageChange = (page) => {
    setCurrentPage(page);
    // 非预渲染页面切换时,SWR会自动重新发起请求
  };

  if (error) return <div>加载失败,请稍后重试</div>;
  // 未预渲染页面在数据加载前显示加载状态
  if (!isPreRendered && !data) return <div>加载中...</div>;

  return (
    <div>
      <h1>第 {currentPage} 页帖子</h1>
      <div className="posts-list">
        {posts.map((post) => (
          <div key={post.id} className="post-card">
            <h2>{post.title}</h2>
            <p>{post.excerpt}</p>
          </div>
        ))}
      </div>
      <div className="pagination">
        {Array.from({ length: 10 }, (_, i) => (
          <button
            key={i+1}
            onClick={() => handlePageChange(i+1)}
            disabled={currentPage === i+1}
            className={currentPage === i+1 ? 'active' : ''}
          >
            {i+1}
          </button>
        ))}
      </div>
    </div>
  );
};

export default PostsPage;

关键细节说明

  • fallback: true:未预渲染的页面会先返回一个包含客户端脚本的空HTML,避免404,之后在客户端动态拉取数据渲染。
  • 如果希望非预渲染页面第一次访问时用服务器端渲染(SSR)、后续缓存,可以把fallback设为'blocking',但这样无法保证数据实时性,需根据需求选择。
  • SWR的缓存机制能让用户切换分页时快速响应,同时可通过配置保证数据新鲜度。

内容的提问来源于stack exchange,提问作者Nishanth B.S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:25:27