You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React分页跳转非首页后搜索返回空结果问题排查修复

问题根因
  • 搜索作用域错误:users状态仅存储当前分页的10条数据,翻页后该状态仅保留对应页内容,前端搜索直接在users上做过滤,无法匹配到其他分页的结果,非首页搜索自然返回空。
  • 搜索未重置分页:非首页状态下offset不为0,触发搜索后分页切片仍从非0位置开始,就算有匹配结果也会被切片逻辑漏掉。
  • 分页参数固定:pageCount始终按全量数据长度计算,搜索后结果总数变化时不会动态更新,容易出现空页。
  • 状态更新不规范:全选逻辑中多余调用getApiData()会覆盖本地增删改后的用户数据;onCheckHandler中直接修改状态数组的元素,违反React状态不可变原则,会引发渲染异常。
修改方案
  1. 数据分层存储:接口仅在组件初始化时拉取一次全量用户数据存入apid,所有搜索过滤先在全量数据上执行,再做分页切片,禁止在单页数据上做全局搜索。
  2. 搜索自动归位:触发搜索时将分页偏移量offset重置为0,强制回到第一页展示搜索结果。
  3. 动态计算分页值:当前页展示数据、总页数都基于搜索过滤后的结果集计算,随搜索关键词变化实时更新。
  4. 修正不规范状态更新:移除全选逻辑中多余的接口调用,所有状态修改采用不可变更新方式,避免直接赋值原状态数组。
核心修正代码

1. 调整数据拉取逻辑

接口仅初始化时拉取一次全量数据,翻页不再重复请求:

const getApiData = async () => {
    const res = await axios.get('https://geektrust.s3-ap-southeast-1.amazonaws.com/adminui-problem/members.json');
    setApid(res.data);
}
// 移除useEffect的offset依赖
useEffect(() => {
    getApiData();
}, []);

2. 新增统一的过滤、分页计算逻辑

用useMemo缓存计算结果,避免重复计算:

import { useEffect, useMemo, useRef, useState } from "react"; // 记得引入useMemo

// 搜索过滤后的全量结果
const filteredUsers = useMemo(() => {
    if (!apid) return [];
    if (!searchValue?.trim()) return apid;
    const keyword = searchValue.toLowerCase().trim();
    return apid.filter(user => 
        user.name.toLowerCase().includes(keyword) ||
        user.email.toLowerCase().includes(keyword) ||
        user.role.toLowerCase().includes(keyword)
    )
}, [apid, searchValue]);

// 当前分页需要展示的数据
const currentPageUsers = useMemo(() => {
    return filteredUsers.slice(offset, offset + perPage);
}, [filteredUsers, offset, perPage]);

// 搜索结果对应的总页数
const currentPageCount = useMemo(() => {
    return Math.ceil(filteredUsers.length / perPage);
}, [filteredUsers.length, perPage]);

3. 修正搜索、分页、全选逻辑

// 搜索时重置到第一页
const searchList = () => {
    setSearchValue(searchRef.current.value);
    setOffset(0);
};

// 分页点击逻辑适配动态结果长度
const handlePageClick = (e) => {
    const selectedOffset = e.selected * perPage;
    setOffset(Math.min(selectedOffset, filteredUsers.length));
};

// 全选逻辑移除多余接口调用
const selectAllVisibleUserRecord = () => {
    setIsCheckAll(prev => !prev);
    if (isCheckAll) {
        setIds([]);
        return;
    }
    setIds(currentPageUsers.map(user => user.id));
};

// 修正编辑用户时的状态更新,不直接修改原数组
const onCheckHandler = userRecord => {
    setUsers(prev => {
        const existIndex = prev.findIndex(record => record.id === userRecord.id);
        if (existIndex === -1) return [userRecord, ...prev];
        const newList = [...prev];
        newList[existIndex] = userRecord;
        return newList;
    })
}

4. 调整渲染部分逻辑

移除表格遍历前多余的filter,直接使用计算好的当前页数据,分页组件传入动态总页数:

{/* 表格内容部分 */}
<tbody>
    {currentPageUsers.map((listdata) => (
        <tr key={listdata.id} className={ids.includes(listdata.id) ? 'checked' : ''}>
            {/* 原有行内容保持不变 */}
        </tr>
    ))}
</tbody>

{/* 分页组件部分 */}
<ReactPaginate
    previousLabel={"prev"}
    nextLabel={"next"}
    breakLabel={"..."}
    breakClassName={"break-me"}
    pageCount={currentPageCount} {/* 替换原来的固定pageCount */}
    pageRangeDisplayed={5}
    onPageChange={handlePageClick}
    containerClassName={"pagination"}
    subContainerClassName={"pages pagination"}
    activeClassName={"active"} 
/>

内容的提问来源于stack exchange,提问作者user2568391

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 16:54:23