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

Expo应用中.filter方法筛选用户列表无返回结果问题排查

Expo+AWS应用用户列表筛选后为空问题修复

问题背景

基于Expo开发、后端依托AWS搭建的社交类应用,需要在拉取用户列表的fetchUsers函数中添加筛选逻辑,过滤掉已与当前认证用户完成匹配的用户,避免用户重复滑动浏览已匹配对象,但调用fetchedUsers.filter方法后未返回任何用户卡片。

已实现的匹配拉取逻辑

首先实现了fetchMatches函数,用于拉取所有和当前认证用户达成匹配的用户数据,代码如下:

useEffect(() => {
  if (!me) {
      return;
  }
  fetchMatches();
 }, [me]);

 const fetchMatches = async () => {
    const result = await DataStore.query(Match, match => 
      match
      .isMatch('eq', true)
      .or(match => match.matchUser1Id('eq', me.id).matchUser2Id('eq', me.id))
      );
  setMatches(result);
  console.warn(result);
}

已实现的用户列表拉取逻辑

后续实现fetchUsers函数,原逻辑为基于已获取的匹配列表,提取匹配关系中的用户ID,和拉取到的全量用户ID做比对,排除ID重合的已匹配用户,代码如下:

useEffect(() => {
  if(!isUserLoading && user) {
    fetchUsers();
  }
}, [me, matches, user]);

const fetchUsers = async () => {
  let fetchedUsers = await DataStore.query(User);
  
    setUsers(fetchedUsers.filter(user => {
      matches.filter(match => 
        match.matchUser1Id !== user.id && match.matchUser2Id !== user.id
      )
    }));
}

问题现象

  • 为fetchedUsers添加上述filter筛选逻辑后,首页未渲染任何用户卡片
  • 移除filter逻辑、直接调用setUsers(fetchedUsers)时,可以正常返回并渲染数据库中的全量用户列表
  • 控制台未出现未处理的Promise报错或其他类型错误,仅存在筛选后列表不渲染的问题

根因分析

问题由3个代码逻辑错误共同导致:

  1. 外层filter回调缺少return语句:fetchedUsers.filter传入的回调使用大括号包裹函数体,但没有写显式return。箭头函数使用大括号包裹函数体时不会自动返回执行结果,默认返回undefined(falsy值),因此所有用户都被判定为不需要保留,直接返回空数组,这是列表为空的核心原因。
  2. 筛选判断逻辑错误:就算补上return语句,内层使用matches.filter也无法得到正确的布尔判断结果。Array.filter返回值始终是数组,而JS中无论数组是否为空,转布尔值时均为truthy,无法正确判定「当前用户是否在已匹配列表中」。
  3. Match查询条件逻辑错误:DataStore查询语法中,or回调内链式调用条件默认是且关系,原代码写的.or(match => match.matchUser1Id('eq', me.id).matchUser2Id('eq', me.id))实际查询的是「匹配记录中user1是me且user2也是me」的无效数据,根本拉取不到正确的已匹配列表。

修复方案

  1. 首先修复fetchMatches的查询条件,正确拉取当前用户的所有已匹配记录:
const fetchMatches = async () => {
  const result = await DataStore.query(Match, match => 
    match
    .isMatch('eq', true)
    .or(match => 
      match.matchUser1Id('eq', me.id).or(innerMatch => innerMatch.matchUser2Id('eq', me.id))
    )
  );
  setMatches(result);
  console.warn(result);
}
  1. 重写fetchUsers的筛选逻辑,做好空值兜底,同时过滤当前登录用户本人避免自滑:
const fetchUsers = async () => {
  let fetchedUsers = await DataStore.query(User);
  // 兜底处理matches未初始化的场景,提取所有匹配关联的用户ID存入Set提升查询性能
  const matchedUserIds = new Set(
    (matches || []).flatMap(match => [match.matchUser1Id, match.matchUser2Id])
  );
  // 把当前登录用户自己加入过滤集合,避免用户滑到自己的卡片
  matchedUserIds.add(me.id);

  setUsers(
    fetchedUsers.filter(user => !matchedUserIds.has(user.id))
  );
}

优化说明:使用Set存储需要过滤的用户ID,单次ID判断的时间复杂度为O(1),相比每次遍历matches数组做判断,在匹配记录较多时性能优势明显。

内容的提问来源于stack exchange,提问作者azoth820

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:36:20