I'm using Apollo Client, and for fetching queries I'm using useQuery
from the package @apollo/react-hooks
.
I would like to accomplish the following:
Step 1: Fetch a query stage
const GetStage = useQuery(confirmStageQuery, {
variables: {
input: {
id: getId.id
}
}
});
Step 2: Based on the response that we get from GetStage
, we would like to switch between 2 separate queries
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
}
}
});
}
Step 3: Also when the page loads every time, I'm re-fetching the data.
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
So how can we call multiple async queries in Apollo Client?
As Philip said, you can't conditionally call hooks. However conditionally calling a query is very common, so Apollo allows you to skip it using the skip
option:
const { loading, error, data: { forum } = {}, subscribeToMore } = useQuery(GET_FORUM, {
skip: !forumId,
fetchPolicy: 'cache-and-network',
variables: { id: forumId },
});
The hook is called, but the query isn't. That's a lot simpler and clearer than using a lazy query for your use case in my opinion.
The rules of hooks say you can't conditionally call hooks, whenever you find yourself in a situation where you want to use an if/else around a hook you're probably on the wrong track.
What you want to do here is to use a lazyQuery for everything that's "optional" or will be fetched later - or for queries that depend on the result of another query.
Here's a quick example (probably not complete enough to make your entire code work):
// 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])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With