gpt4 book ai didi

reactjs - 如何在 React 和 Typescript 中映射我的联合类型 GraphQL 响应数组

转载 作者:行者123 更新时间:2023-12-04 17:07:53 25 4
gpt4 key购买 nike

我正在使用 React、Typescript 和 Apollo Client。

在我的 React 组件中,我使用 useQuery hook NODES_TYPE_ONENODES_TYPE_TWO 查询,基于值 blockData.myType .这很好用。

GraphQL 查询看起来像:

export const NODES_TYPE_ONE = gql`
query GetNodesOne($customKey: String!) {
getNodesTypeOne(customKey: $customKey) {
nodes {
id
title
}
}
}
`;

export const NODES_TYPE_TWO = gql`
query GetNodesTwo($customKey: String!) {
getNodesTypeTwo(customKey: $customKey) {
nodes {
id
title
}
}
}
`;

但是如何在 GqlRes 类型中输入我的数据?

当我 console.log(data); 我得到:两个不同的对象:

getNodesTypeOne {
nodes[// array of objects]
}

getNodesTypeTwo {
nodes[// array of objects]
}

我的 GqlRes 类型:

export type GqlRes = {
getNodesTypeOne: {
nodes: NodeTeaser[];
};
};

/** @jsx jsx */
import { useQuery } from '@apollo/client';
import { jsx } from '@emotion/react';

import { Slides } from 'app/components';

import { NODES_TYPE_ONE, NODES_TYPE_TWO } from './MyBlock.gql';
import { Props, GqlRes, NodesArgs } from './MyBlock.types';

const MyBlock = ({ data: blockData, metadata }: Props) => {
const customKey = metadata.customKey;

const { data } = useQuery<GqlRes, NodesArgs>(
blockData.myType === 'type-one' ? NODES_TYPE_ONE : NODES_TYPE_TWO,
{
variables: {
customKey: metadata.customKey || 0,
},
errorPolicy: 'all',
notifyOnNetworkStatusChange: true,
ssr: false,
}
);

const items =
data?.getNodesTypeOne.nodes.map((video) => {
return {
id: video.uuid,
type: 'type-one',
title: title,
};
}) || [];


return <Slides items={items} /> : null;
};

export default MyBlock;

现在我的项目只返回 getNodesTypeOne 但我如何同时获得它们?

更新:

我为 GqlRes 创建了一个联合类型:

type GetNodeTypeOne = {
getNodesTypeOne: {
nodes: Teaser[];
};
};

type GetNodeTypeTwo = {
getNodesTypeTwo: {
nodes: Teaser[];
};
};

export type GqlRes = GetNodeTypeOne | GetNodeTypeTwo;

但是我现在如何映射节点数组呢?

更新 2

正如@Urmzd 所提到的,我尝试了另一种方法。只需使用多个 useQuery 钩子(Hook):

const MyBlock = ({ data: blockData, metadata }: Props) => {
const customKey = metadata.customKey;

const { data: nodesOne } = useQuery<NodesOneGqlRes, NodesArgs>(NODES_TYPE_ONE,
{
variables: {
customKey: metadata.customKey || 0,
},
errorPolicy: 'all',
notifyOnNetworkStatusChange: true,
ssr: false,
}
);

const { data: nodesTwo } = useQuery<NodesTwoGqlRes, NodesArgs>(NODES_TYPE_TWO,
{
variables: {
customKey: metadata.customKey || 0,
},
errorPolicy: 'all',
notifyOnNetworkStatusChange: true,
ssr: false,
}
);


const items =
data?.// How do I get my nodes in a single variable?? .map((video) => {
return {
id: video.uuid,
type: 'type-one',
title: title,
};
}) || [];


return <Slides items={items} /> : null;
};

export default MyBlock;

但是我现在如何映射我的数据,因为我有两个不同的 GraphQL 响应?在这种情况下最好的方法是什么?

最佳答案

如果我直接理解你的代码,那么根据 blockData.myType 的值,你要么执行一个查询,要么执行另一个查询,并且你想重用相同的 useQuery这个逻辑的钩子(Hook)。如果你想要,你需要确保 GqlResunion type getNodesTypeOnegetNodesTypeTwo

// I don't know what NodeType is so I'm just using a string for this example
type NodeType = string

interface GetNodesTypeOne {
readonly getNodesTypeOne: {
readonly nodes: NodeType[]
}
}

interface GetNodesTypeTwo {
readonly getNodesTypeTwo: {
readonly nodes: NodeType[]
}
}

type GqlRes = GetNodesTypeOne | GetNodesTypeTwo

const resultOne:GqlRes = {
getNodesTypeOne: {
nodes: [ "test" ]
}
}

const resultTwo:GqlRes = {
getNodesTypeTwo: {
nodes: [ "test" ]
}
}

所以这将解决 TypeScript 问题。然后稍后在您的代码中执行此操作:

  const items = data?.getNodesTypeOne.nodes.map(...)

由于 data 可能包含 getNodesTypeOnegetNodesTypeTwo 我们需要将其更改为其他内容。一个快速的解决方法是只选择第一个有值的:

const nodes = "getNodesTypeOne" in data 
? data?.getNodesTypeOne?.nodes
: data?.getNodesTypeTwo?.nodes
const items = nodes.map(...);

或者如果你想使用相同的条件:

const nodes = blockData.myType === 'type-one'
? (data as GetNodesTypeOne)?.getNodesTypeOne?.nodes
: (data as GetNodesTypeTwo)?.getNodesTypeTwo?.nodes
const items = nodes.map(...);

请注意,在第二个示例中,我们需要通过 narrowing 帮助 TypeScript 确定具体类型使用 type assertion 将其关闭.在第一个示例中,这不是必需的,因为 TypeScript 足够聪明,可以确定第一个表达式将始终生成 GetNodesTypeOne,而第二个表达式将始终生成 GetNodesTypeOne .


使用两个单独的查询来回答您的第二个问题:

  • 添加一个新变量 useQueryOne 如果我们正在运行查询一,该变量为 true,如果我们正在运行查询二,则为 false .
  • skip 添加到 useQuery 以仅运行适当的查询。
  • 添加一个新变量 nodes,其中包含第一个或第二个查询的结果(基于 useQueryOne 条件)
const useQueryOne = blockData.myType === 'type-one';

const { data: nodesOne } = useQuery<NodesOneGqlRes, NodesArgs>(NODES_TYPE_ONE,
{
variables: {
customKey: metadata.customKey || 0,
},
errorPolicy: 'all',
notifyOnNetworkStatusChange: true,
ssr: false,
skip: !useQueryOne
}
);

const { data: nodesTwo } = useQuery<NodesTwoGqlRes, NodesArgs>(NODES_TYPE_TWO,
{
variables: {
customKey: metadata.customKey || 0,
},
errorPolicy: 'all',
notifyOnNetworkStatusChange: true,
ssr: false,
skip: useQueryOne
}
);

const nodes = useQueryOne
? nodesOne?.getNodesTypeOne?.nodes
: nodesTwo?.getNodesTypeTwo?.nodes;
const items = (nodes || []).map(...);

关于reactjs - 如何在 React 和 Typescript 中映射我的联合类型 GraphQL 响应数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70154670/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com