如何为带分页的自定义React Table组件添加搜索功能
解决React自定义Table组件搜索与分页联动问题
你的问题核心是Table组件内部状态未跟随父组件传入的过滤后数据更新,导致搜索后分页数据不刷新、页码状态异常。以下是具体修复方案:
问题根源
- 组件初始化时仅通过
initDataShow设置dataShow初始值,但父组件搜索触发filteredItems变化时,dataShow状态不会自动更新,仍保留旧数据。 - 当前页
currPage未随数据总量变化重置,搜索后若结果总页数小于当前页码,会出现空数据或页码无效的情况。
修复步骤
1. 添加useEffect监听props变化
引入useEffect监听props.bodyData和props.limit的变化,每次变化时重新计算初始显示数据并重置当前页。
2. 优化分页逻辑
确保pages和range的计算始终基于最新的props.bodyData,避免使用过期值。
修改后的Table组件代码
import React, { useState, useEffect } from "react"; import "./table.css"; const Table = (props) => { const [dataShow, setDataShow] = useState([]); const [currPage, setCurrPage] = useState(0); // 监听props变化,重新初始化数据和页码 useEffect(() => { const limit = Number(props.limit); // 计算初始显示的数据(第一页) const initialData = props.bodyData ? props.bodyData.slice(0, limit || props.bodyData.length) : []; setDataShow(initialData); // 重置当前页为0 setCurrPage(0); }, [props.bodyData, props.limit]); // 基于最新props计算分页信息 const pages = (() => { if (!props.limit || !props.bodyData) return 1; const limit = Number(props.limit); const total = props.bodyData.length; const pageCount = Math.floor(total / limit); return total % limit === 0 ? pageCount : pageCount + 1; })(); const range = [...Array(pages).keys()]; const selectPage = (page) => { const limit = Number(props.limit); const start = limit * page; const end = start + limit; setDataShow(props.bodyData.slice(start, end)); setCurrPage(page); }; return ( <div> <div className="table-wrapper"> <table> {props.headData && props.renderHead ? ( <thead> <tr> {props.headData.map((item, index) => props.renderHead(item, index) )} </tr> </thead> ) : null} {props.bodyData && props.renderBody ? ( <tbody> {dataShow.map((item, index) => props.renderBody(item, index))} </tbody> ) : null} </table> </div> {pages > 1 ? ( <div className="table__pagination"> {range.map((item, index) => ( <div key={index} className={`table__pagination-item ${ currPage === index ? "active" : "" }`} onClick={() => selectPage(index)} > {item + 1} </div> ))} </div> ) : null} </div> ); }; export default Table;
关键修改说明
- 移除原本的
initDataShow变量,改用useEffect在props变化时动态初始化dataShow。 - 每次搜索导致
props.bodyData更新时,自动重置currPage为0,确保显示第一页的过滤结果。 - 将
pages的计算改为立即执行函数,确保每次渲染都基于最新的props.bodyData和props.limit。
你的搜索逻辑(父组件中的filteredItems)是正确的,修改Table组件后即可实现搜索与分页的联动效果。
内容的提问来源于stack exchange,提问作者yusufff
相关产品推荐
相关产品推荐

