在React + Apollo Client中如何根据节点type值条件发起GraphQL请求
解决方案
首先先修正你当前GraphQL查询文件的导出错误:同一个模块不能有两个export default,先改为命名导出:
// MyBlock.gql export const NodeTypeOne = gql` query NodeTypeOne { getNodesOne { nodes { id type title } } } `; export const NodeTypeTwo = gql` query NodeTypeTwo { getNodesTwo { nodes { id type title } } } `;
之后有两种简洁的实现方式可选:
方式一:动态匹配查询(最常用)
提前维护类型和查询的映射关系,根据传入的类型直接匹配对应查询传入useQuery即可:
import { useQuery } from '@apollo/client'; import { NodeTypeOne, NodeTypeTwo } from './MyBlock.gql'; // 类型和查询的映射表 const QUERY_MAP = { NodeTypeOne: NodeTypeOne, NodeTypeTwo: NodeTypeTwo } as const; const MyBlock = ({ data: myType }: Props) => { const targetQuery = QUERY_MAP[myType as keyof typeof QUERY_MAP]; const { data } = useQuery<GqlRes>(targetQuery, { skip: !targetQuery // 无匹配查询时跳过请求,避免报错 }); // 统一取返回的节点数据 const nodes = data?.getNodesOne?.nodes || data?.getNodesTwo?.nodes || []; const items = nodes.map(node => ({ id: node.id, title: node.title })); return items.length ? <Slider items={items} /> : null; }; export default MyBlock;
方式二:合并查询用指令控制(适合字段复用率高的场景)
可以把两个查询合并为一个,通过GraphQL原生的@skip指令控制返回哪部分数据,不需要维护多个查询文件:
// MyBlock.gql export default gql` query GetNodes($skipTypeOne: Boolean!, $skipTypeTwo: Boolean!) { getNodesOne @skip(if: $skipTypeOne) { nodes { id type title } } getNodesTwo @skip(if: $skipTypeTwo) { nodes { id type title } } } `;
组件逻辑更简洁:
import { useQuery } from '@apollo/client'; import NodesQuery from './MyBlock.gql'; const MyBlock = ({ data: myType }: Props) => { const { data } = useQuery<GqlRes>(NodesQuery, { variables: { skipTypeOne: myType !== 'NodeTypeOne', skipTypeTwo: myType !== 'NodeTypeTwo' } }); const nodes = data?.getNodesOne?.nodes || data?.getNodesTwo?.nodes || []; const items = nodes.map(node => ({ id: node.id, title: node.title })); return items.length ? <Slider items={items} /> : null; }; export default MyBlock;
内容的提问来源于stack exchange,提问作者meez
相关产品推荐
相关产品推荐

