[英]How to make a second api call with data received from the first api call in Apollo client with React?
I'm developing an Apollo GraphQL API for the Star Wars API ( https://swapi.dev/api/ ).我正在为星球大战 API ( https://swapi.dev/api/ ) 开发一个 Apollo GraphQL API。 I want to make a second API call using the data I get from the first API call in order to get the name property of the hometown in the second API call.
我想使用从第一个 API 调用中获得的数据进行第二个 API 调用,以便在第二个 API 调用中获取家乡的名称属性。 I have managed to make the first API call, I'm now stuck on making the second API call using the data from the first api call.
我已经成功拨打了第一个 API 电话,我现在坚持使用来自第一个 api 电话的数据进行第二个 API 电话。
My code for the first API call is shown below: (index.js)我的第一个 API 调用代码如下所示:(index.js)
const restLink = new RestLink({ uri: "https://swapi.dev/api/" }); const client = new ApolloClient({ link: restLink, cache: new InMemoryCache(), });
First API call:先拨打API:
import { useQuery, gql } from "@apollo/client"; const GET_CHARACTERS = gql` query { people @rest(path: "people/") { results { name height mass gender homeworld } } } `; const { error: peopleError, data: peopleData, loading: peopleLoading, } = useQuery(GET_CHARACTERS); return { peopleError, peopleData, peopleLoading, };
First API call is sent to: https://swapi.dev/api/people/ and it returns the object with data shown below (I have only shown the first object):第一个 API 调用被发送到: https://swapi.dev/api/people/它返回 object,数据如下所示(我只显示了第一个对象):
{ name: "Luke Skywalker", height: 172, age: 77, gender: "male", hometown: "https://swapi.dev/api/pl.nets/1/" }
After getting this, I have to make another call to the API ( https://swapi.dev/api/pl.nets/1/ ) that is brought back by hometown object key so that when I display the data, it will show the name property of the hometown in the API. The hometown API will have data like the one shown below:得到这个之后,我必须再次调用家乡object 密钥带回的 API ( https://swapi.dev/api/pl.nets/1/ ) 这样当我显示数据时,它会显示API 中家乡的名称属性。家乡 API 将具有如下所示的数据:
{ "name": "Tatooine", "rotation_period": "23", "orbital_period": "304", "diameter": "10465", "climate": "arid", "gravity": "1 standard", "terrain": "desert", "surface_water": "1", "population": "200000", }
This is what is called a "Dependent Query".这就是所谓的“依赖查询”。 You can read about your exact case here: https://www.apollographql.com/blog/apollo-client/using-apollo-link-to-handle-dependent-queries/
你可以在这里阅读你的确切案例: https://www.apollographql.com/blog/apollo-client/using-apollo-link-to-handle-dependent-queries/
The main thing is to use the skip
option in your query configuration, like so:最主要的是在查询配置中使用
skip
选项,如下所示:
const { data: profileData } = useQuery(PROFILE_INFO)
const planetId = profileData?.planet?.id
const { data: planetData } = useQuery(PLANET,
skip: !planetId, // Only run this query if the first query has completed
variables: { planetId }
)
The challenge you are facing isn't "how to call a dependent query" as your title implies, but rather "how to call a dynamic number of queries".正如您的标题所暗示的那样,您面临的挑战不是“如何调用依赖查询”,而是“如何调用动态数量的查询”。
React Query refers to this as dynamic parallel queries and provides a useQueries
(notice the plural) hook to work with it. React Query 将此称为动态并行查询,并提供一个
useQueries
(注意复数)钩子来处理它。 Apollo appears to not have such a feature . Apollo 似乎没有这样的功能。 On the same issue, a GitHub user has posted their implementation of a
useQueries
hook for Apollo that you could use like so:在同一问题上,一位 GitHub 用户发布了他们为 Apollo 实现的
useQueries
挂钩,您可以像这样使用它:
const graphResults = useQueries(
graphs.map(graph => ({
query: GET_INSIGHT,
variables: { ...graph, interval, from, to },
/* specific useQuery options */
})),
{ /* general useQuery options */ },
);
In my opinion, a more appropriate solution to this is to solve it by writing your own hook for any query that requires N calls by invoking the Apollo client directly using ApolloClient.query
.在我看来,一个更合适的解决方案是通过使用
ApolloClient.query
直接调用 Apollo 客户端来为任何需要 N 次调用的查询编写自己的钩子来解决它。 Here is my go at it with another schema:这是我的 go 和另一个模式:
function useRates(currencies) {
const client = useApolloClient();
const [results, setResults] = useState({});
useEffect(() => {
let isStale = false;
setResults({});
for (let currency of currencies) {
const rates = client.query({
query: ratesQuery,
variables: { currency }
});
rates.then((result) => {
if (!isStale)
setResults((results) => ({ ...results, [currency]: result.data.rates }));
});
}
return () => (isStale = true);
}, [client, currencies.join(",")]);
return results;
}
Demo: https://codesandbox.io/s/get-started-coinbase-client-forked-lfwtig?file=%2Fsrc%2Findex.js%3A744-1316演示: https://codesandbox.io/s/get-started-coinbase-client-forked-lfwtig?file=%2Fsrc%2Findex.js%3A744-1316
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.