6

I'm trying to integrate react-query into my React project. What I have is a custom hook - useBundles which fetches data from a GraphQl endpoint as shown below -

function useBundles() {

  const { data, status, isSuccess } = useQuery(
    'SaleBundles',
    async () => await request(endpoint, gql`query {${saleQuery}}`),
  );

  return { data, status, isSuccess };
}

I use the return value in my component like this const { data, status, isSuccess } = useBundles(); which works perfectly fine.

Now, what I want to do is, for each item in data I want to call another endpoint (a REST endpoint this time) and I have a seperate async function for that called getData(data: Array) which uses async-await to fetch data from my REST endpoint.

I could just call getData in useBundles passing to it data as an argument. But since getData is async it is required to use await with it (which I can't because I can't define a hook as async).

As an alternative, I tried not to use getData in useBundles but directly call the endpoint using axios like this - data.forEach((item) => useQuery("some-unique-key", axios.get(<endpoint>)))

This gives me an error saying that useQuery cannot be used in a loop.

I'm kinda stuck at this point as how to proceed. Would appreciate any help. Thanks.

1 Answer 1

6

There are basically two ways to solve this:

  1. useQueries

useQueries can be used with a fixed array, but also with a dynamic one, so:

useQueries(data.map(item => ...))

would work. It will give you an array of QueryResults back.

  1. map and create a component
data.map(item => <Item {...item} />

then, you can call useQuery inside the Item component.


Both approaches will yield concurrent requests, the difference is mainly where you have access to the response data: With useQueries, you have access to all of them in your root component. With the second approach, each Item will only have access to its own data. So it just depends on your needs / use-case which version you prefer.

Sign up to request clarification or add additional context in comments.

4 Comments

I'm a bit confused here, can you provide a more explicit example using useQueries for my use-case?
instead of using useQuery in a loop, useQueries.
const results = useQueries( saleBundles.map((bundle) => { return { queryKey: ['SaleBundle', bundle.id], queryFn: async () => await fetchData(bundle, bundleTypes.sale), }; }), ); I'm doing this but on first load, results is an array of items and status is loading, so data is undefined
code looks right. status will be loading when the items are still fetching. As they come in one by one, those items in the array will go into success state.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.