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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:34:03