GraphQL数组筛选指定类型元素:旧版客户端空对象解决方案咨询
解决方案:过滤GraphQL数组中未知类型的空对象
针对你遇到的旧版客户端请求课程数据时,lessons数组出现空对象的问题,有两种可行的解决方式:
1. 全局缓存策略处理(推荐)
通过Apollo Client的typePolicies配置,让缓存自动过滤无效的空对象,所有用到Course.lessons的地方都会生效:
修改你的客户端初始化代码,给InMemoryCache添加类型策略:
import { ApolloClient, InMemoryCache } from "@apollo/client"; import Config from "services/config"; export const sanityApolloClient = new ApolloClient({ uri: Config.GRAPHQL_URL, cache: new InMemoryCache({ typePolicies: { Course: { fields: { lessons: { merge(existing, incoming) { // 只保留有有效字段且类型为TextLesson的元素 return incoming.filter(item => Object.keys(item).length > 0 && item.__typename === 'TextLesson' ); } } } } } }), headers: { Authorization: `Bearer ${Config.GRAPHQL_API_TOKEN}`, }, defaultOptions: { watchQuery: { fetchPolicy: "cache-and-network", }, }, });
这个merge函数会在缓存更新或收到网络响应时自动执行,过滤掉数组中那些因客户端未定义对应片段而生成的空对象。
2. 查询结果手动过滤
如果不需要全局处理,也可以在获取到查询结果后,手动过滤lessons数组:
import { useQuery } from '@apollo/client'; import { GetCourse } from './your-queries'; function CourseComponent() { const { data } = useQuery(GetCourse); // 过滤掉空对象 const validLessons = data?.Course?.lessons?.filter(lesson => Object.keys(lesson).length > 0 ) || []; return ( <div> {validLessons.map(lesson => ( <div key={lesson.title}>{lesson.title}</div> ))} </div> ); }
或者用useMemo优化性能:
import { useMemo } from 'react'; // ... const validLessons = useMemo(() => { return data?.Course?.lessons?.filter(lesson => lesson.__typename === 'TextLesson') || []; }, [data]);
原因说明
出现空对象是因为后端返回了VideoLesson类型的数据,但旧版客户端的查询中没有定义该类型的片段匹配,Apollo Client无法解析该类型的字段,因此生成了空对象。通过上述两种方式,都可以只保留客户端能识别的TextLesson元素。
内容的提问来源于stack exchange,提问作者Waltari
相关产品推荐
相关产品推荐

