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

React中如何在排序时触发渲染(含筛选与分页功能)

问题:切换排序选项后车辆列表无法自动更新,仅切换分页才生效

相关代码

Sort.js 组件

<SortWrapper>
  <SortText>Sort By</SortText>
  <SortSelect onChange={onSelectChange}>
    <SortOption value="vehicleMake">Vehicle make</SortOption>
    <SortOption value="vehicleModel">Vehicle model</SortOption>
  </SortSelect>
</SortWrapper>

App.js 中渲染 Sort 组件的代码

<Sort onSelectChange={onSelectChange} />

排序处理函数

const onSelectChange = (e) => {
  const value = e.target.value;

  if (value === "VehicleMake")
    vehicles.sort((a, b) => a.vehicleMake.localeCompare(b.vehicleMake));
  else if (value === "VehicleModel") {
    vehicles.sort((a, b) => a.vehicleModel.localeCompare(b.vehicleModel));
  } else {
    vehicles.sort((a, b) => a.id - b.id);
  }
}

Grid 组件代码

<Grid>
  {vehiclesData.map((vehicle) => (
    <VehicleCard
      id={vehicle.id}
      key={vehicle.id}
      ImageURL={vehicle.ImageURL}
      vehicleMake={vehicle.vehicleMake}
      vehicleModel={vehicle.vehicleModel}
      selectVehicle={() => setSelectedVehicle(vehicle)}
      deleteHandler={() => deleteHandler(vehicle.id)}
    />
  ))}
</Grid>

筛选与分页处理函数

const vehiclesData = useMemo(() => {
  let computedVehicles = vehicles;

  if (searchVehicle) {
    computedVehicles = computedVehicles.filter((vehicle) =>
      vehicle.vehicleMake.toLowerCase().includes(searchVehicle.toLowerCase())
    );
  }

  setTotalVehicles(computedVehicles.length);

  return computedVehicles.slice(
    (currentPage - 1) * vehiclesPerPage,
    (currentPage - 1) * vehiclesPerPage + vehiclesPerPage
  );
})

问题场景

vehicles 是从 Firestore 获取的对象数组。切换 SortOption 的值时,数组不会自动排序渲染,只有点击分页第2页再切回第1页时,排序才会生效。希望切换排序选项后,车辆列表能自动渲染排序结果,无需切换分页。

解决方案

问题根源有两个:

  1. 直接原地修改数组,未触发 React 状态更新;
  2. 排序判断的字符串大小写与选项值不匹配,导致逻辑未执行。

具体修复步骤

  1. 修正大小写匹配 + 触发状态更新
    复制原数组进行排序,再通过状态 setter 更新,让 React 检测到变化触发渲染:

    const onSelectChange = (e) => {
      const value = e.target.value;
      // 复制原数组避免原地修改
      const sortedVehicles = [...vehicles];
    
      if (value === "vehicleMake") {
        sortedVehicles.sort((a, b) => a.vehicleMake.localeCompare(b.vehicleMake));
      } else if (value === "vehicleModel") {
        sortedVehicles.sort((a, b) => a.vehicleModel.localeCompare(b.vehicleModel));
      } else {
        sortedVehicles.sort((a, b) => a.id - b.id);
      }
      // 更新状态触发重新渲染
      setVehicles(sortedVehicles);
      // 排序后重置到第一页,避免当前页无数据
      setCurrentPage(1);
    }
    

    注:假设你用 const [vehicles, setVehicles] = useState([]) 管理车辆数组状态。

  2. 完善 useMemo 依赖项
    给 vehiclesData 的 useMemo 添加所有相关依赖,确保值变化时重新计算:

    const vehiclesData = useMemo(() => {
      let computedVehicles = [...vehicles];
    
      if (searchVehicle) {
        computedVehicles = computedVehicles.filter((vehicle) =>
          vehicle.vehicleMake.toLowerCase().includes(searchVehicle.toLowerCase())
        );
      }
    
      return computedVehicles.slice(
        (currentPage - 1) * vehiclesPerPage,
        (currentPage - 1) * vehiclesPerPage + vehiclesPerPage
      );
    }, [vehicles, searchVehicle, currentPage, vehiclesPerPage]); // 补充所有依赖
    
  3. 移除 useMemo 内的状态更新
    把总数计算移到单独的 useEffect,避免 useMemo 内触发额外渲染:

    useEffect(() => {
      let computedVehicles = [...vehicles];
      if (searchVehicle) {
        computedVehicles = computedVehicles.filter((vehicle) =>
          vehicle.vehicleMake.toLowerCase().includes(searchVehicle.toLowerCase())
        );
      }
      setTotalVehicles(computedVehicles.length);
    }, [vehicles, searchVehicle]);
    

完成以上修改后,切换排序选项时会自动更新车辆列表,无需切换分页即可看到排序结果。

内容的提问来源于stack exchange,提问作者Luka Modrić

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 19:04:53