如何在React类组件中结合Axios实现表格分页功能
解决方案
本次实现的是前端分页方案,适配你当前一次性拉取全量用户数据的场景,修改内容如下:
- state新增分页核心参数:当前页码
currentPage、每页展示条数pageSize - 搜索关键词变更时自动重置页码到第一页,避免出现页码超出总页数的空白情况
- 对过滤后的用户数据做切片渲染,仅展示当前页对应数据
- 新增分页控制器UI,完全适配Tailwind CSS样式
完整修改后代码
import React, { Component } from "react"; import axios from "axios"; import Search from "../components/Search"; import Users from "../Users"; class UsersManagement extends Component { constructor(props) { super(props); this.state = { users: [], search: "", sort: ["Oldest", "Newest"], currentSort: "Oldest", // 补充排序状态管理,修复原代码排序功能依赖props的问题 currentPage: 1, // 新增:当前页码 pageSize: 10, // 新增:每页展示条数,可自行调整 }; } componentDidMount() { axios .get("http://localhost/crud-user/php/users.php") .then((res) => { this.setState({ users: res.data }); }) .catch(function (error) { console.log(error); }); } displayUsers() { // 1. 先过滤搜索结果 let filteredUsers = this.state.users.filter( (user) => user.first_name .toLowerCase() .includes(this.state.search.toLowerCase()) || user.last_name.toLowerCase().includes(this.state.search.toLowerCase()) ); // 2. 处理排序逻辑(补充原缺失的排序功能) filteredUsers = filteredUsers.sort((a, b) => { if (this.state.currentSort === "Newest") { return new Date(b.created_at) - new Date(a.created_at); } return new Date(a.created_at) - new Date(b.created_at); }); // 3. 按当前页切片数据 const paginatedUsers = filteredUsers.slice( (this.state.currentPage - 1) * this.state.pageSize, this.state.currentPage * this.state.pageSize ); return paginatedUsers.map(function (object, index) { return <Users obj={object} key={index} />; }); } // 新增:获取过滤后总数据条数、总页数 getPaginationInfo() { const filteredUsers = this.state.users.filter( (user) => user.first_name .toLowerCase() .includes(this.state.search.toLowerCase()) || user.last_name.toLowerCase().includes(this.state.search.toLowerCase()) ); return { total: filteredUsers.length, totalPages: Math.ceil(filteredUsers.length / this.state.pageSize), }; } render() { const { total, totalPages } = this.getPaginationInfo(); return ( <div className="flex flex-col"> <div className="w-full text-center leading-10 mt-10"> <span className="text-black not-italic font-extrabold text-5xl"> USER MANAGEMENT </span> </div> <div className="md:px-32 w-screen mt-10"> <div className="flex overflow-hidden w-10/12 mx-auto"> <div className="w-full mb-5"> <Search onSearch={(e) => this.setState({ search: e.target.value, currentPage: 1 })} /> </div> <div className="w-full mb-5 text-right"> <select name="sort" value={this.state.currentSort} onChange={(e) => this.setState({ currentSort: e.target.value, currentPage: 1 })} className="border-2 border-black rounded-xl h-12 px-5 outline-none cursor-pointer" > {this.state.sort.map((sort) => ( <option className="cursor-pointer" value={sort} key={sort}> {sort} </option> ))} </select> </div> </div> <div className="overflow-hidden w-10/12 mx-auto"> <table className="min-w-full bg-white"> <thead className="bg-white text-black border-b-2 border-gray-500"> <tr> <th className="w-1/5 text-left py-3 px-4 font-semibold text-lg"> User ID </th> <th className="w-1/4 text-left py-3 px-4 font-semibold text-lg"> Name </th> <th className="w-1/4 text-left py-3 px-4 font-semibold text-lg"> E-mail </th> <th className="text-center py-3 px-4 font-semibold text-lg"> Phone Number </th> <th className="text-center py-3 px-4 font-semibold text-lg"> Birthdate </th> </tr> </thead> <tbody className="text-black"> {total > 0 ? ( this.displayUsers() ) : ( <tr> <td colSpan="5" className="py-5 text-center"> <p className="text-lg text-red-700 cursor-default"> No data available! </p> </td> </tr> )} </tbody> </table> </div> {/* 新增分页控制器 */} {total > 0 && ( <div className="flex justify-between items-center mt-6 w-10/12 mx-auto"> <span className="text-gray-700">共 {total} 条数据</span> <div className="flex gap-2"> <button onClick={() => this.setState(prev => ({ currentPage: prev.currentPage - 1 }))} disabled={this.state.currentPage === 1} className="px-4 py-2 border rounded-lg disabled:bg-gray-100 disabled:cursor-not-allowed hover:bg-gray-50 transition-colors" > 上一页 </button> <span className="px-4 py-2 flex items-center"> {this.state.currentPage} / {totalPages} </span> <button onClick={() => this.setState(prev => ({ currentPage: prev.currentPage + 1 }))} disabled={this.state.currentPage === totalPages} className="px-4 py-2 border rounded-lg disabled:bg-gray-100 disabled:cursor-not-allowed hover:bg-gray-50 transition-colors" > 下一页 </button> </div> </div> )} </div> </div> ); } } export default UsersManagement;
补充说明
如果后续数据量过大,前端分页性能不足,可以改为后端分页:请求接口时携带page和pageSize参数,后端返回对应页数据和总条数即可,仅需要修改Axios请求逻辑和分页参数计算逻辑,前端UI不需要调整。
内容的提问来源于stack exchange,提问作者tdmayk
相关产品推荐
相关产品推荐

