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}> ← 上一页 </button> <span className="pagination-page-info"> 第 {currentPage} 页 / 共 {totalPages} 页 </span> <button className="pagination-button" onClick={handleNextPage} disabled={currentPage === totalPages}> 下一页 → </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
相关产品推荐
相关产品推荐

