React.js中加载时禁用所有分页按钮且不影响分页功能的实现
实现分页按钮加载时禁用的解决方案
关键修改点
- 让数据加载逻辑响应页码变化,适配分页请求场景
- 利用
loading状态统一控制所有分页按钮的禁用状态 - 优化加载状态展示,避免页面整体替换
修改后的完整代码
import React, { useState, useEffect } from "react"; import "./styles.css"; export default function App() { const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(false); const [currentPage, setCurrentPage] = useState(0); const [postsPerPage, setPostsPerPage] = useState(10); const [totalPosts, setTotalPosts] = useState(0); useEffect(() => { getData(currentPage); }, [currentPage]); async function getData(page) { setLoading(true); // 模拟接口请求延迟,真实场景替换为带分页参数的接口调用 await new Promise(resolve => setTimeout(resolve, 800)); const response = await fetch('https://stream-restaurant-menu-svc.herokuapp.com/item?category'); let actualData = await response.json(); // 客户端模拟分页切片,服务端分页直接取接口返回的当前页数据即可 const startIndex = page * postsPerPage; const endIndex = startIndex + postsPerPage; const pageData = actualData.slice(startIndex, endIndex); setPosts(pageData); setTotalPosts(actualData.length); setLoading(false); } const pageNumbers = []; for (let i = 0; i < Math.ceil(totalPosts / postsPerPage); i++) { pageNumbers.push(i); } const incrementPageNumber = () => { if (currentPage < pageNumbers.length - 1) { setCurrentPage(prev => prev + 1); } }; const decrementPageNumber = () => { if (currentPage > 0) { setCurrentPage(prev => prev - 1); } }; return ( <div className="App"> <table className="table"> <thead> <tr> <th>ID</th> <th>First Name</th> <th>Last Name</th> </tr> </thead> <tbody> {loading ? ( <tr> <td colSpan="3" style={{ textAlign: 'center' }}>Loading...</td> </tr> ) : ( posts.map((post) => ( <tr key={post.id}> <td>{post.id}</td> <td>{post.name}</td> <td>{post.short_name}</td> </tr> )) )} </tbody> </table> <div> <button id='first' type='button' className='first-page-btn' disabled={loading || currentPage === 0} onClick={() => setCurrentPage(0)} > first </button> <button id='previous' type='button' className='previous-page-btn' disabled={loading || currentPage === 0} onClick={decrementPageNumber} > previous </button> <button id='next' type='button' className='next-page-btn' disabled={loading || currentPage === pageNumbers.length - 1} onClick={incrementPageNumber} > next </button> <button id='last' type='button' className='last-page-btn' disabled={loading || currentPage === pageNumbers.length - 1} onClick={() => setCurrentPage(pageNumbers.length - 1)} > last </button> </div> </div> ); }
核心逻辑说明
- 页码联动加载:将
useEffect依赖改为currentPage,每次切换页码自动触发对应页的数据加载。 - 加载状态控禁用:所有分页按钮的
disabled属性都包含loading状态,确保加载过程中无法重复点击。 - 修复按钮禁用逻辑:修正原代码中Last按钮的错误禁用条件,改为判断是否处于最后一页。
- 友好加载提示:在表格内显示加载状态,而非替换整个页面,保留页面布局的连贯性。
- 适配真实场景:模拟接口延迟的部分可直接替换为带分页参数的后端接口调用,无缝切换到服务端分页模式。
内容的提问来源于stack exchange,提问作者Lyon
相关产品推荐
相关产品推荐

