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页时,排序才会生效。希望切换排序选项后,车辆列表能自动渲染排序结果,无需切换分页。
解决方案
问题根源有两个:
- 直接原地修改数组,未触发 React 状态更新;
- 排序判断的字符串大小写与选项值不匹配,导致逻辑未执行。
具体修复步骤
修正大小写匹配 + 触发状态更新
复制原数组进行排序,再通过状态 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([])管理车辆数组状态。完善 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]); // 补充所有依赖移除 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ć
相关产品推荐
相关产品推荐

