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

React/TypeScript分页功能异常求助:点击分页按钮页码变更但数据未更新

分页功能失效的问题定位与修复方案

嘿,我帮你找出了几个导致分页功能失效的核心问题,下面逐个拆解并给出修复后的代码:

1. API请求URL参数写错了

你当前的请求URL里的分页参数格式完全错误:&?${page}这种写法不符合CoinGecko API的要求,正确的分页参数应该是page=${page},而且URL里的参数分隔符用&就好(&是HTML转义字符,在JS的fetch请求里不需要用)。

错误的URL片段:

`...&?${page}&per_page=10...`

修正后的完整URL:

`https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&page=${page}&per_page=10&sparkline=false`

2. useEffect没有依赖数组,请求逻辑异常

你的useEffect没有设置依赖项,这会导致组件每次渲染都调用fetchData,不仅浪费请求,而且逻辑上应该只有当page变化时才重新获取对应页码的数据。必须把page加入到useEffect的依赖数组中,确保页码变更时触发新的请求。

3. totalPages完全没正确更新

你写的setTotalPages(totalPages)相当于把总页数设置成它自己的初始值10,等于没更新。CoinGecko的这个API会在响应头的x-total-count字段返回总数据量,我们可以用这个值计算总页数:Math.ceil(总数据量 / 每页条数),也就是Math.ceil(totalCount / 10)。

4. 分页按钮的处理函数逻辑冗余且易出错

你给handlePrevPage和handleNextPage传了currentPage参数,但在setPage的函数式更新里又用了同名变量,这会覆盖state的前值,完全没必要。函数式更新本身就能获取到当前的page状态,所以处理函数不需要接收参数。


修复后的Coins组件代码

import React, {lazy, Suspense, useEffect, useState} from 'react'
import {Coin} from '../../interface'
import './Coins.css'
import Pagination from "./Pagination";
const CoinTable = lazy(() => import('../../components/CoinData/CoinTable'))

export const Coins:React.FC = () => {
  const [coinsData, setCoinsData] = useState<Coin[]>([])
  const [page, setPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);

  // 简化分页处理函数,不需要传入参数
  const handlePrevPage = () => {
    setPage(prevPage => prevPage - 1);
  };

  const handleNextPage = () => {
    setPage(prevPage => prevPage + 1);
  };

  const fetchData= async()=>{
    try {
      const response= await fetch(`https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&page=${page}&per_page=10&sparkline=false`)
      // 从响应头获取总数据量,计算总页数
      const totalCount = Number(response.headers.get('x-total-count'));
      setTotalPages(Math.ceil(totalCount / 10));
      
      const result = await response.json()
      setCoinsData(result);
    } catch (error) {
      console.error('获取加密货币数据失败:', error);
    }
  }

  useEffect(()=>{
    fetchData()
    // 只有page变化时才重新请求数据
  }, [page])

  return (
    <>
      <Suspense fallback={<div>加载中...</div>}>
        <table className="table" width="80%">
          <thead>
            <tr>
              <th>Cryptocurrencies</th>
              <th>Price</th>
              <th>24H Change</th>
              <th>Market Cap</th>
            </tr>
          </thead>
        </table>
        {coinsData.map((coin)=>(
          <CoinTable key={coin.id} {...coin} />
        ))}
        <Pagination 
          totalPages={totalPages} 
          currentPage={page} 
          handlePrevPage={handlePrevPage} 
          handleNextPage={handleNextPage} 
        />
      </Suspense>
    </>
  )
}

修复后的Pagination组件代码

因为我们修改了处理函数不需要参数,所以这里的点击事件直接绑定函数即可:

import React from "react";
import PropTypes from "prop-types";

interface Props {
  currentPage: number;
  totalPages: number;
  handleNextPage: () => void; // 移除参数
  handlePrevPage: () => void; // 移除参数
}

const Pagination:React.FC <Props>= ({
  currentPage,
  totalPages,
  handlePrevPage,
  handleNextPage,
}) => {
  return (
    <div className="pagination-button-wrapper">
      <button className="pagination-button" onClick={handlePrevPage} disabled={currentPage === 1}>
        &larr; 上一页
      </button>
      <span className="pagination-page-info">
        第 {currentPage} 页 / 共 {totalPages} 页
      </span>
      <button className="pagination-button" onClick={handleNextPage} disabled={currentPage === totalPages}>
        下一页 &rarr;
      </button>
    </div>
  );
};

Pagination.propTypes = {
  currentPage: PropTypes.number.isRequired,
  totalPages: PropTypes.number.isRequired,
  handlePrevPage: PropTypes.func.isRequired,
  handleNextPage: PropTypes.func.isRequired,
};

export default Pagination

额外优化点

  • 加了try/catch捕获请求错误,方便你调试;
  • 给分页按钮补全了文本,之前的下一页按钮是空的;
  • 现在点击分页按钮时,page状态更新,触发useEffect重新请求对应页码的数据,表格就会同步更新了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 15:37:50