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,提问作者Лео
相关产品推荐
相关产品推荐

