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

如何在NextJS中正确实现文章分类筛选与分页功能

解决Next.js中文章筛选与分页的联动问题

你当前的代码核心问题是分页操作直接基于原始articles数组,没有和筛选后的结果联动,导致筛选后分页逻辑依然沿用全部文章的计算。正确的逻辑是先筛选文章,再对筛选后的结果执行分页,同时还要处理分类切换时的页码重置,避免出现无内容的无效页码。

具体修改步骤

1. 调整分页数据源

将分页操作的数据源从原始articles替换为筛选后的filteredArticles,确保分页只针对当前选中分类下的文章:

// 原代码
// const paginatePosts = paginate(articles, currentPage, pageSize, selectedTag);
// 修改后
const paginatePosts = paginate(filteredArticles, currentPage, pageSize);

注:如果你的paginate函数不需要selectedTag参数,直接移除即可——筛选逻辑已经提前完成,分页无需再依赖分类标签。

2. 更新分页组件的总条目数

让分页器基于筛选后的文章数量计算总页数,避免出现“总页数与实际内容不匹配”的问题:

// 原代码
// items={articles.length}
// 修改后
items={filteredArticles.length}

3. 分类切换时重置页码

切换分类后自动回到第1页,防止用户停留在超出筛选结果总页数的页码上(比如原文章有12条在第2页,筛选后只剩3条,此时第2页会显示空内容):

// 在Index组件中新增分类切换处理函数
const handleTagChange = (tag) => {
  setSelectedTag(tag);
  setCurrentPage(1);
  router.push(`?page=1`, undefined, { shallow: true });
};

然后将Category组件的setSelectedTag替换为这个新函数:

<Category
  tag={tag}
  key={tag}
  selectedTag={selectedTag}
  setSelectedTag={handleTagChange} // 替换为新函数
  onPageChange={handlePageChange}
/>

修改后的完整Index组件代码

export default function Index({ articles, categories }) {
  const [selectedTag, setSelectedTag] = useState<string>(null);
  const filteredArticles = filterArticles(articles, selectedTag);
  const articleItems = [
    <Image className="h-full w-full" src={card1} alt="teste" />,
    <Image className="h-full w-full" src={card2} alt="teste" />,
    <Image className="h-full w-full" src={card3} alt="teste" />,
    <Image className="h-full w-full" src={card4} alt="teste" />,
    <Image className="h-full w-full" src={card1} alt="teste" />,
  ];

  const [currentPage, setCurrentPage] = useState(1);
  const pageSize = 6;
  const router = useRouter();
  
  // 处理分类切换,自动重置页码
  const handleTagChange = (tag) => {
    setSelectedTag(tag);
    setCurrentPage(1);
    router.push(`?page=1`, undefined, { shallow: true });
  };

  const handlePageChange = (page) => {
    setCurrentPage(page);
    router.push(`?page=${page}`, undefined, { shallow: true });
  };

  // 基于筛选后的文章执行分页
  const paginatePosts = paginate(filteredArticles, currentPage, pageSize);

  return (
    <Layout>
      <HeroHeader />
      <div className="flex flex-wrap justify-center gap-4 pt-8  dark:bg-slate-900 ">
        {categories.map((tag) => (
          <Category
            tag={tag}
            key={tag}
            selectedTag={selectedTag}
            setSelectedTag={handleTagChange}
            onPageChange={handlePageChange}
          />
        ))}
      </div>
      <Container>
        <div>
          <div className="my-8 text-3xl font-bold text-gray-900 dark:text-gray-100 ">
            {!selectedTag ? "Сүүлд нийтэлсэн" : `${selectedTag}`}
          </div>
          <ArticleList articles={paginatePosts} />
          <BlogPagination
            items={filteredArticles.length}
            pageSize={pageSize}
            currentPage={currentPage}
            onPageChange={handlePageChange}
          />
        </div>
      </Container>
    </Layout>
  );
}

额外说明

  • 如果你的paginate函数原本设计为同时处理筛选和分页,现在可以简化它的逻辑——只需要接收数组、当前页码、每页数量三个参数即可,筛选逻辑已经提前完成。
  • 修改后,筛选和分页会完全联动:切换分类自动回到第一页,分页器显示的总页数匹配当前分类的文章数量,列表仅展示当前页的筛选后内容。

内容的提问来源于stack exchange,提问作者Tugulduroch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 13:55:06