如何在 Apollo Client React 中获取多个条件查询?
How to fetch multiple conditional queries in Apollo Client React?
我使用的是 Apollo Client,为了获取查询,我使用的是包 @apollo/react-hooks
.
中的 useQuery
我想完成以下任务:
步骤列表:
步骤 1: 获取查询 stage
const GetStage = useQuery(confirmStageQuery, {
variables: {
input: {
id: getId.id
}
}
});
第 2 步: 根据我们从 GetStage
获得的响应,我们想在 2 个单独的查询之间切换
if (!GetStage.loading && GetStage.data.getGame.stage === "Created") {
Details = useQuery(Query1, {
variables: {
input: {
id: getId.id
}
}
});
} else if (!GetStage.loading && GetStage.data.getGame.stage === "Confirmed") {
Details = useQuery(Query2, {
variables: {
input: {
id: getId.id
}
}
});
}
第 3 步:另外,每次加载页面时,我都会重新获取数据。
useEffect(() => {
//Fetch for Change in the Stage
GetStage.refetch();
//Fetch for Change in the Object
if (Details) {
Details.refetch();
if (Details.data) {
setDetails(Details.data.getGame);
}
}
});
有问题吗?
Rendered more hooks than during the previous render.
Details.data is undefined
那么我们如何在 Apollo Client 中调用多个异步查询呢?
The rules of hooks 说你不能有条件地调用 hooks,每当你发现自己处于想在 hook 周围使用 if/else 的情况时,你可能走错了路。
您想在这里做的是对 "optional" 或稍后获取的所有内容使用 lazyQuery - 或者对依赖于另一个查询结果的查询。
这是一个简单的示例(可能不够完整,无法使您的整个代码正常工作):
// This query is always called, use useQuery
const GetStage = useQuery(confirmStageQuery, {
variables: {
input: {
id: getId.id
}
}
});
const [fetchQuery1, { loading1, data1 }] = useLazyQuery(Query1);
const [fetchQuery2, { loading2, data2 }] = useLazyQuery(Query2);
// Use an effect to execute the second query when the data of the first one comes in
useEffect(() => {
if (!GetStage.loading && GetStage.data.getGame.stage === "Created") {
fetchQuery1({variables: {
input: {
id: getId.id
}
}})
} else if (!GetStage.loading && GetStage.data.getGame.stage === "Confirmed") {
fetchQuery2({variables: {
input: {
id: getId.id
}
}})
}
}, [GetState.data, GetStage.loading])
正如 Philip 所说,你不能有条件地调用 hooks。然而,有条件地调用查询非常普遍,因此 Apollo 允许您使用 skip
选项跳过它:
const { loading, error, data: { forum } = {}, subscribeToMore } = useQuery(GET_FORUM, {
skip: !forumId,
fetchPolicy: 'cache-and-network',
variables: { id: forumId },
});
已调用挂钩,但未调用查询。在我看来,这比对您的用例使用惰性查询要简单和清晰得多。
我使用的是 Apollo Client,为了获取查询,我使用的是包 @apollo/react-hooks
.
useQuery
我想完成以下任务:
步骤列表:
步骤 1: 获取查询 stage
const GetStage = useQuery(confirmStageQuery, {
variables: {
input: {
id: getId.id
}
}
});
第 2 步: 根据我们从 GetStage
获得的响应,我们想在 2 个单独的查询之间切换
if (!GetStage.loading && GetStage.data.getGame.stage === "Created") {
Details = useQuery(Query1, {
variables: {
input: {
id: getId.id
}
}
});
} else if (!GetStage.loading && GetStage.data.getGame.stage === "Confirmed") {
Details = useQuery(Query2, {
variables: {
input: {
id: getId.id
}
}
});
}
第 3 步:另外,每次加载页面时,我都会重新获取数据。
useEffect(() => {
//Fetch for Change in the Stage
GetStage.refetch();
//Fetch for Change in the Object
if (Details) {
Details.refetch();
if (Details.data) {
setDetails(Details.data.getGame);
}
}
});
有问题吗?
Rendered more hooks than during the previous render.
Details.data is undefined
那么我们如何在 Apollo Client 中调用多个异步查询呢?
The rules of hooks 说你不能有条件地调用 hooks,每当你发现自己处于想在 hook 周围使用 if/else 的情况时,你可能走错了路。
您想在这里做的是对 "optional" 或稍后获取的所有内容使用 lazyQuery - 或者对依赖于另一个查询结果的查询。
这是一个简单的示例(可能不够完整,无法使您的整个代码正常工作):
// This query is always called, use useQuery
const GetStage = useQuery(confirmStageQuery, {
variables: {
input: {
id: getId.id
}
}
});
const [fetchQuery1, { loading1, data1 }] = useLazyQuery(Query1);
const [fetchQuery2, { loading2, data2 }] = useLazyQuery(Query2);
// Use an effect to execute the second query when the data of the first one comes in
useEffect(() => {
if (!GetStage.loading && GetStage.data.getGame.stage === "Created") {
fetchQuery1({variables: {
input: {
id: getId.id
}
}})
} else if (!GetStage.loading && GetStage.data.getGame.stage === "Confirmed") {
fetchQuery2({variables: {
input: {
id: getId.id
}
}})
}
}, [GetState.data, GetStage.loading])
正如 Philip 所说,你不能有条件地调用 hooks。然而,有条件地调用查询非常普遍,因此 Apollo 允许您使用 skip
选项跳过它:
const { loading, error, data: { forum } = {}, subscribeToMore } = useQuery(GET_FORUM, {
skip: !forumId,
fetchPolicy: 'cache-and-network',
variables: { id: forumId },
});
已调用挂钩,但未调用查询。在我看来,这比对您的用例使用惰性查询要简单和清晰得多。