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

如何为基于Jikan Anime API的React应用实现分页功能?

实现Jikan Anime API的React分页功能

核心思路

要实现分页,需要管理当前页码状态、动态传递页码给API请求,并利用API返回的分页数据控制按钮状态,具体步骤如下:


步骤1:添加页码状态管理

在组件顶部引入useState,用来存储当前页码:

import { useState } from 'react';

// ... 其他代码 ...

const [currentPage, setCurrentPage] = useState(1);

步骤2:动态传递页码给API请求

把原来固定的1替换成currentPage,这样页码变化时会自动触发新的请求:

const {
    data: manga = [],
    isLoading,
    isFetching,
    error,
} = useGetAnimeQuery(currentPage);

步骤3:解构分页控制字段

从API返回的pagination中提取关键字段,用来判断分页按钮的可用状态:

const { data: top_anime, pagination } = manga;
const { current_page, last_page, has_next_page, has_prev_page } = pagination || {};

步骤4:实现分页按钮逻辑

编写页码切换的函数,同时做边界值限制(比如不能小于1,不能大于总页数):

const goToPrevPage = () => {
    if (has_prev_page) {
        setCurrentPage(prev => prev - 1);
    }
};

const goToNextPage = () => {
    if (has_next_page) {
        setCurrentPage(prev => prev + 1);
    }
};

步骤5:渲染分页控件

在预留的button容器中添加分页按钮和页码信息:

<div className="button text-yellow-500 flex items-center justify-center gap-4 mt-2 pb-2">
    <button 
        onClick={goToPrevPage}
        disabled={!has_prev_page || isFetching}
        className="px-4 py-2 bg-gray-700 rounded disabled:opacity-50 disabled:cursor-not-allowed"
    >
        上一页
    </button>
    <span>第 {current_page || 1} 页 / 共 {last_page || 1} 页</span>
    <button 
        onClick={goToNextPage}
        disabled={!has_next_page || isFetching}
        className="px-4 py-2 bg-gray-700 rounded disabled:opacity-50 disabled:cursor-not-allowed"
    >
        下一页
    </button>
</div>

修改后的完整组件代码

import { useState } from 'react';
import { useGetAnimeQuery } from './your-api-slice-path'; // 替换成你的API切片路径
import Spinner from './Spinner'; // 替换成你的Spinner组件路径
import TopAnime from './TopAnime'; // 替换成你的TopAnime组件路径

const TopAnimeList = () => {
    const [currentPage, setCurrentPage] = useState(1);

    const {
        data: manga = [],
        isLoading,
        isFetching,
        error,
    } = useGetAnimeQuery(currentPage);

    const { data: top_anime, pagination } = manga;
    const { current_page, last_page, has_next_page, has_prev_page } = pagination || {};

    if (isLoading) {
        return <Spinner color_1="#141e30" color_2="#243b55" />;
    }

    if (isFetching) {
        return <Spinner color_1="#141e30" color_2="#243b55" />;
    }

    if (error) {
        console.log("ERROR =>", error.message);
        return <div className="text-white text-center py-8">加载失败,请稍后重试</div>;
    }

    const goToPrevPage = () => {
        if (has_prev_page) {
            setCurrentPage(prev => prev - 1);
        }
    };

    const goToNextPage = () => {
        if (has_next_page) {
            setCurrentPage(prev => prev + 1);
        }
    };

    return (
        <section className="bg-gradient-to-r from-[#141e30] to-[#243b55]">
            <div className="container font-poppins">
                <div className="grid grid-cols-4 gap-3 place-items-center px-20 py-4">
                    {top_anime?.map((anime) => (
                        <TopAnime anime={anime} key={anime.mal_id} />
                    ))}
                </div>
                <div className="button text-yellow-500 flex items-center justify-center gap-4 mt-2 pb-4">
                    <button 
                        onClick={goToPrevPage}
                        disabled={!has_prev_page || isFetching}
                        className="px-4 py-2 bg-gray-700 rounded disabled:opacity-50 disabled:cursor-not-allowed"
                    >
                        上一页
                    </button>
                    <span>第 {current_page || 1} 页 / 共 {last_page || 1} 页</span>
                    <button 
                        onClick={goToNextPage}
                        disabled={!has_next_page || isFetching}
                        className="px-4 py-2 bg-gray-700 rounded disabled:opacity-50 disabled:cursor-not-allowed"
                    >
                        下一页
                    </button>
                </div>
            </div>
        </section>
    );
};

export default TopAnimeList;

关键细节说明

  • 按钮添加disabled属性,避免用户在无更多页或加载中重复点击
  • 保留isFetching状态的判断,切换页码时显示加载动画,提升用户体验
  • 对pagination做空值处理,避免API返回异常时出现报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:40:38