React服务端分页场景下如何实现筛选条件切换页面时持久生效
问题根因
- 未持久化存储当前激活的筛选参数,分页切换逻辑无法感知是否处于筛选状态
- 取数逻辑分散在useEffect、筛选触发回调、分页回调三个地方,没有统一复用,导致分页回调始终调用不带筛选参数的全量接口
- 分页回调中
skip参数计算错误,原代码直接传page值,正确应为pageSize * (page - 1)
修复步骤
- 父组件新增筛选参数状态,统一封装取数逻辑
- 筛选触发时更新筛选状态、重置页码为1,调用统一取数函数
- 分页回调仅更新分页状态,由useEffect监听状态变化自动触发带筛选参数的取数请求
- 新增筛选清空逻辑,清空输入时重置筛选状态回到全量数据模式
完整修改后代码
const ParentComponent = () => { const [values, setValues] = useState([]); const [pageCount, setPageCount] = useState(0); const [page, setPage] = useState(1); const [pageSize, setPageSize] = useState(7); const [loading, setLoading] = useState(false); // 新增:存储当前激活的筛选参数 const [filterParams, setFilterParams] = useState({}); // 新增:统一封装取数逻辑,所有场景都调用这个函数 const fetchData = async () => { setLoading(true); const skip = pageSize * (page - 1); // 拼接基础分页参数+筛选参数 const params = new URLSearchParams({ skip, take: pageSize, ...filterParams }); try { const res = await axios.get(`http://localhost:3000/api/v1/elements?${params.toString()}`); setValues(res.data.data); setPageCount(res.data.count); } catch (err) { console.error(err); } finally { setLoading(false); } }; // 依赖项新增筛选参数、pageSize,所有分页/筛选变化自动触发取数 useEffect(() => { fetchData(); }, [page, pageSize, filterParams]); const handleCurrentPage = (value) => setPage(value); const handlePageSize = (value) => setPageSize(value); // 向子组件传递对应props return <ChildComponent page={page} pageSize={pageSize} pageCount={pageCount} values={values} loading={loading} setFilterParams={setFilterParams} handleCurrentPage={handleCurrentPage} handlePageSize={handlePageSize} /> }
const ChildComponent = (props) => { const { page, pageSize, pageCount, values, loading, setFilterParams, handleCurrentPage, handlePageSize } = props; const columns = [ { title: 'dealership', width: 125, dataIndex: 'Dealership', key: 'Dealership', fixed: 'left', filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => { return ( <div style={{ padding: 8, width: '12.8rem' }}> <Input autoFocus placeholder="Enter dealership" value={selectedKeys[0]} onChange={(e) => { setSelectedKeys(e.target.value ? [e.target.value] : []); }} onPressEnter={async () => { confirm(); const keyword = selectedKeys[0]?.trim(); if (keyword) { // 存储筛选参数,同时重置页码到第一页 setFilterParams({ name: keyword }); handleCurrentPage(1); } else { // 输入为空时清空筛选,回到全量数据 setFilterParams({}); } }} /> <Button onClick={() => { clearFilters(); setFilterParams({}); handleCurrentPage(1); }} style={{ marginTop: 8, marginRight: 8 }} > 清空筛选 </Button> </div> ) } } ]; return ( <Table columns={columns} dataSource={values} loading={loading} scroll={{ x: 1300 }} pagination={{ pageSize: pageSize, current: page, total: pageCount, onChange: (newPage, newPageSize) => { // 仅更新分页状态,useEffect会自动触发带筛选参数的取数 handlePageSize(newPageSize); handleCurrentPage(newPage); } }} size="middle" /> ) }
额外优化点
- 所有取数逻辑统一管理,后续新增筛选条件只需要更新
filterParams即可,无需修改多处接口调用逻辑 - 筛选时自动重置页码为1,避免筛选后总条数不足当前页码导致的空数据问题
- 新增清空筛选按钮,支持快速回到全量数据模式
- 修复了原分页逻辑中
skip参数计算错误的问题
内容的提问来源于stack exchange,提问作者0pablot
相关产品推荐
相关产品推荐

