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

Next.js 13 Server Component分页失效问题求助

Next.js 13 Server Component 无客户端脚本分页实现方案

你当前的核心问题是没有根据URL中的limit参数过滤返回的文章数量,导致每次点击按钮虽然URL更新了,但页面始终渲染全部文章。下面是具体的修复步骤:

1. 修改getAllPosts函数,支持传入limit参数

让函数接受可选的limit参数,返回对应数量的文章(默认返回全部):

import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';

interface Blog {
  meta: any;
  slug: string;
}

// 添加limit可选参数,控制返回文章数量
export function getAllPosts(limit?: number) {
  const blogDir = "blog";
  const files = fs.readdirSync(path.join(blogDir));

  const blogs: Blog[] = files.map((filename: string) => {
    const fileContent = fs.readFileSync(path.join(blogDir, filename), 'utf-8');
    const { data: frontMatter } = matter(fileContent);

    return {
      meta: frontMatter,
      slug: filename.replace('.mdx', '')
    };
  });

  // 根据limit参数截取对应数量的文章
  if (limit) {
    return blogs.slice(0, limit);
  }
  return blogs;
}

2. 在Blog页面中使用limit参数过滤文章

从searchParams中获取limit值,转成数字后传给getAllPosts,同时渲染对应数量的文章:

import Link from 'next/link'
import { HomeProps } from "@/types";

import { getAllPosts } from '@/lib/getAllData'
import ShowMore from '@/components/loadmore'

export default function Blog({searchParams } : HomeProps) {
    // 从URL参数获取limit,默认显示1篇
    const currentLimit = Number(searchParams.limit) || 1;
    // 传入limit参数获取对应数量的文章
    const blogs = getAllPosts(currentLimit);
    // 获取全部文章总数,用于判断是否还有更多内容
    const totalPosts = getAllPosts().length;

    return (
        <main className="flex flex-col">
            <h1 className="text-3xl font-bold">
                Мой блог
            </h1>

            <section className='py-10'>
                <div className='py-2'>
                    {blogs.map((blog) => (
                        <Link href={`/blog/${blog.slug}`} passHref key={blog.slug}>
                            <div className='py-2 flex justify-between items-center gap-2'>
                                <div>
                                    <h3 className="text-lg font-bold">{blog.meta.title}</h3>
                                    <p className="text-gray-400">{blog.meta.description}</p>
                                </div>
                                <div className="my-auto text-gray-400">
                                    <p>{blog.meta.date}</p>
                                </div>
                            </div>
                        </Link>
                    ))}

                    <ShowMore
                        pageNumber={currentLimit}
                        isNext={currentLimit >= totalPosts}
                    />
                </div>
            </section>
        </main>
    )
}

3. 优化ShowMore组件逻辑

调整新增文章数量的计算逻辑,让它更贴合需求:

"use client";

import { useRouter } from "next/navigation";

import { ShowMoreProps } from "@/types";
import { updateSearchParams } from "@/utils";

const ShowMore = ({ pageNumber, isNext  }: ShowMoreProps) => {
  const router = useRouter();

  const handleNavigation = () => {
    // 直接在当前显示数量基础上加1,实现每次新增1篇的需求
    const newLimit = pageNumber + 1;
    const newPathname = updateSearchParams("limit", `${newLimit}`);

    router.push(newPathname);
  };

  return (
    <div className="w-full flex-center gap-5 mt-10">
      {!isNext && (
        <button
          title="Show More"
          onClick={handleNavigation}
        >Кнопка</button>
       )}
    </div>
  );
};

export default ShowMore;

关键修复点说明

  • getAllPosts新增limit参数:通过slice(0, limit)返回指定数量的文章,这是实现分页的核心逻辑
  • Blog页面传递limit:从URL的searchParams中提取参数,传给getAllPosts,让Server Component根据参数动态渲染对应数量的内容
  • 修正isNext判断:用当前显示数量和总文章数对比,准确判断是否还有更多内容可以加载

内容的提问来源于stack exchange,提问作者Лео

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 16:53:32