如何在React TypeScript中过滤嵌套数组?现有代码求整合方案
解决方案
你需要把**「仅保留包含有效服务(locationPerformsService为true)的地点」**这个逻辑,和原有的「关键词过滤」逻辑合并到同一个filter回调里,以下是具体实现:
1. 简化嵌套数组验证逻辑
不用手动遍历收集服务数组,直接用数组的some方法快速判断当前地点是否存在符合要求的服务:
// 判断地点是否有至少一个有效服务 const hasValidServices = location.services.some(service => service.locationPerformsService);
some方法会在找到第一个符合条件的元素后立即停止遍历,比手动forEach+判断数组长度更高效。
2. 合并过滤逻辑到原有代码
把上述判断和原有的关键词过滤结合,修改后的完整代码如下:
<List> {locations.filter(location => { // 验证嵌套数组:是否存在有效服务 const hasValidServices = location.services.some(service => service.locationPerformsService); // 关键词过滤逻辑 const matchesQuery = query === '' || location.name.toLowerCase().includes(query.toLowerCase()); // 两个条件同时满足才保留该地点 return hasValidServices && matchesQuery; }).map((location) => ( <UnstyledButton key={location.risCode} {/* 建议用唯一标识risCode作为key,比index更稳定 */} className={ selectedLocation.risCode === location.risCode ? 'selected-location-navbar-item location-navbar-item' : 'location-navbar-item' } > {/* 这里可以渲染地点名称或服务信息 */} {location.name} </UnstyledButton> ))} </List>
3. 优化:提前处理过滤后的地点(可选)
如果需要在组件其他地方复用过滤后的地点数据,或者避免每次渲染重复执行过滤逻辑,可以用useMemo缓存结果:
import { useMemo } from 'react'; // ...组件内部 const filteredLocations = useMemo(() => { return locations.filter(location => { const hasValidServices = location.services.some(service => service.locationPerformsService); const matchesQuery = query === '' || location.name.toLowerCase().includes(query.toLowerCase()); return hasValidServices && matchesQuery; }); }, [locations, query]); // 依赖项变化时才重新计算 // 渲染时直接用filteredLocations <List> {filteredLocations.map((location) => ( <UnstyledButton key={location.risCode} className={selectedLocation.risCode === location.risCode ? 'selected-location-navbar-item location-navbar-item' : 'location-navbar-item'} > {location.name} </UnstyledButton> ))} </List>
补充说明
- 原代码中
filter回调里的return ... && location写法可以简化,直接返回布尔值即可,filter会自动保留返回true的元素。 - 建议用
location.risCode作为map的key,而不是index,这样当列表顺序变化时React能更高效地更新DOM。
内容的提问来源于stack exchange,提问作者Pam Gaiguer
相关产品推荐
相关产品推荐

