React Native中如何根据id过滤SectionList组件数据
React Native 按指定ID过滤SectionList数据源实现方案
SectionList 要求传入的sections属性是带分组结构的数组,过滤时不要直接修改接口返回的原始数据,避免后续切换过滤条件时丢失全量数据,按以下步骤实现即可:
1. 拆分状态,保留原始数据备份
单独存两份状态,一份存接口返回的全量原始数据(全程不做修改,作为过滤的数据源基底),一份存过滤后实际传给SectionList渲染的分组数据,再存目标过滤ID即可:
import { useState, useEffect } from 'react'; import { SectionList } from 'react-native'; // 原始全量数据,仅接口返回时赋值,不做任何修改 const [allMatches, setAllMatches] = useState([]); // 过滤后传给SectionList的渲染数据 const [filteredSections, setFilteredSections] = useState([]); // 目标过滤ID,可从路由参数、筛选组件等位置获取 const [targetFilterId, setTargetFilterId] = useState(null);
原接口请求代码混用了async/await和Promise链式调用,简化优化后如下:
const getAllMatches = async () => { try { const res = await fetch(APIS?.Matches, { method: 'GET', headers: { Authorization: user, Accept: 'application/json', 'Content-Type': 'application/json', }, }); const { matches = [] } = await res.json(); setAllMatches(matches); } catch (err) { console.error('获取赛事列表失败:', err); } };
2. 编写过滤逻辑
过滤时需要同时处理两层:外层遍历分组,内层过滤组内匹配ID的条目,最后剔除过滤后没有有效条目的空分组,避免渲染无内容的分组头部。
如果你的过滤维度是分组本身的ID,直接在外层遍历分组时做判断即可;如果是过滤组内条目,按下面的逻辑处理
const filterMatchList = (filterId) => { // 未传过滤ID时,直接使用全量数据渲染 if (!filterId) { setFilteredSections(allMatches); return; } const filteredResult = allMatches.reduce((sectionList, currentSection) => { // 替换成你实际业务里的ID字段名,比如sportId、leagueId、categoryId都可以 const matchedItems = currentSection.data.filter(item => item.bizId === filterId); // 仅保留过滤后仍有有效条目的分组 if (matchedItems.length > 0) { sectionList.push({ ...currentSection, // 保留原分组的title、自定义配置等字段 data: matchedItems }); } return sectionList; }, []); setFilteredSections(filteredResult); };
3. 绑定触发时机与组件渲染
通过useEffect监听两个触发场景:一是接口拉取完全量原始数据后做初始化过滤,二是目标过滤ID变化时自动重新计算过滤结果,最后把过滤后的数据传给SectionList即可:
// 自动触发过滤 useEffect(() => { if (allMatches.length > 0) { filterMatchList(targetFilterId); } }, [allMatches, targetFilterId]); // 渲染SectionList <SectionList sections={filteredSections} keyExtractor={(item) => item.id} renderItem={({ item }) => <MatchCard data={item} />} renderSectionHeader={({ section }) => <SectionHeader title={section.title} />} // 其余原有配置保持不变 />
常见踩坑提醒
- 不要直接在
allMatches状态上修改做过滤,否则切换不同ID过滤时,原始数据已经被上一次操作污染,无法得到正确结果 - 做ID匹配时注意值类型一致,比如接口返回ID是字符串、传入的过滤ID是数字时,统一转成同类型再比较,避免
'123' !== 123导致过滤失效 - 如果接口返回的
matches是扁平数组结构,需要先按业务分组维度(比如赛事类型、日期)转换成SectionList要求的{ title: 分组名, data: 组内条目数组 }结构,再存入allMatches状态
内容的提问来源于stack exchange,提问作者Muhammad Usman
相关产品推荐
相关产品推荐

