如何基于选中的评分复选框过滤API返回的经销商数据,取消勾选时恢复数据
核心问题&修复方案
你的代码存在3个核心问题导致取消勾选后无法正确恢复数据:
- React的
setState是异步更新的,修改activeFilter后立刻读取的还是修改前的旧值,过滤逻辑用了错误的旧过滤条件 - 你直接修改了
activeFilter原数组(用push),没有生成新数组,会导致状态更新不触发重渲染 - 没有处理
activeFilter为空(所有复选框都取消勾选)的场景,此时应该直接返回原始的全量经销商数据
修复后完整代码
import { useState } from 'react'; // Dealer类型定义 export interface Dealer{ dealer_id:number, name:string, mobile:number, email:string, gst_no:string, locality:string, city:string, state:string, pincode:string, vehicle_type_id:number, Vehicletype:{ vehicle_type:string }; Services:[ { discription:string, cost:number } ], dealer_history:[ { rating:number, comments:string } ] } export default function DealerList() { const [dealersData, setDealersData] = useState<Dealer[]>([]); const [filteredData, setFilteredData] = useState<Dealer[]>(dealersData); const [activeFilter, setActiveFilter] = useState<number[]>([]); const onFilterChange = (e: React.ChangeEvent<HTMLInputElement>) => { const targetRating = Number(e.target.value); let newActiveFilter: number[]; if (e.target.checked) { // 生成新数组,不修改原状态 newActiveFilter = [...activeFilter, targetRating]; } else { newActiveFilter = activeFilter.filter(val => val !== targetRating); } setActiveFilter(newActiveFilter); // 用最新的过滤条件计算结果 let ratingResult: Dealer[] = []; // 没有选中任何过滤条件,直接返回原始全量数据 if (newActiveFilter.length === 0) { ratingResult = [...dealersData]; } else { // 按最高选中星级匹配过滤规则,符合你「选2星展示1+2星、选1星仅展示1星」的需求 const maxSelectedRating = Math.max(...newActiveFilter); switch(maxSelectedRating){ case 1: ratingResult = dealersData.filter(dealer => dealer.dealer_history.some(item => item.rating === 1) ); break; case 2: ratingResult = dealersData.filter(dealer => dealer.dealer_history.some(item => item.rating >=1 && item.rating <=2) ); break; case 3: ratingResult = dealersData.filter(dealer => dealer.dealer_history.some(item => item.rating === 3) ); break; case 4: ratingResult = dealersData.filter(dealer => dealer.dealer_history.some(item => item.rating === 4) ); break; case 5: ratingResult = dealersData.filter(dealer => dealer.dealer_history.some(item => item.rating === 5) ); break; } } setFilteredData(ratingResult); } return ( <div> <div><Checkbox color="primary" value="5" onChange={onFilterChange} /><Rating name="size-small" size="small" value={5} readOnly /></div> <div><Checkbox color="primary" value="4" onChange={onFilterChange} /><Rating name="size-small" size="small" value={4} readOnly /></div> <div><Checkbox color="primary" value="3" onChange={onFilterChange} /><Rating name="size-small" size="small" value={3} readOnly /></div> <div><Checkbox color="primary" value="2" onChange={onFilterChange} /><Rating name="size-small" size="small" value={2} readOnly /></div> <div><Checkbox color="primary" value="1" onChange={onFilterChange} /><Rating name="size-small" size="small" value={1} readOnly /></div> {/* 此处补充渲染filteredData的业务逻辑 */} </div> ) }
额外优化说明
- 如果需要支持同时选中多个不连续的星级(比如同时选3星和5星,仅展示3星和5星的经销商),可以调整过滤逻辑为保留所有符合任意选中星级条件的结果,再按经销商ID去重即可
- 原始全量数据
dealersData永远不要直接修改,所有过滤逻辑都基于它计算,就不会出现数据丢失无法恢复的问题
内容的提问来源于stack exchange,提问作者Gagandeep Singh
相关产品推荐
相关产品推荐

