2

Every piece of documentation shows async calls being used with react-query, but I am a little confused why these are necessary, as the following code works with or without async/await:

export const apiCall = (method, path, data) => {
    return axios({method, url: API_PREFIX + path, data})
        .then(resp => resp.data)
        .catch(error => {

        });
};

export const useData = () => {
    const {data, isLoading, error, refetch} = useQuery(
        'users',
        async () => await apiCall(dispatch, 'get', '/some-endpoint'),
    );

    return {
        userList: data,
        refetch,
        isLoading
    }
}
1
  • I don't think so that is necessary, useQuery("users", () => apiCall(dispatch, "get", "/some-endpoint")); this should also work, I think only expectation here is function should return promise. Commented Dec 17, 2021 at 4:54

1 Answer 1

16

react-query wants you to return a resolved or rejected promise - you can produce this however you want. JavaScript has many options to produce promises. async / await is basically just an alternative syntax to promise chaining with .then and .catch.

The code you've posted also works, however, it also has some unnecessary bits:

async () => await apiCall(dispatch, 'get', '/some-endpoint'),

you don't need async / await here, because apiCall already returns a Promise, so this would be the same:

() => apiCall(dispatch, 'get', '/some-endpoint'),

additionally, I wouldn't .catch inside the apiCall function, because it would transform failed Promises to successful Promises. With react-query, you'd really want the failed Promise to be returned to react-query so that the library can do the error handling for you. Otherwise, it doesn't know about the error and can't do retries / cannot give you error states etc.

so for apiCall, these two things would also be equivalent and would work nicely with react-query:

export const apiCall = (method, path, data) => {
    return axios({method, url: API_PREFIX + path, data})
        .then(resp => resp.data)
};
export const apiCall = async (method, path, data) => {
    const response = await axios({method, url: API_PREFIX + path, data})
    return respons.data
};

this really just depends on which syntax you like more - most people prefer async / await because it avoids excessive callback chains.

I've written a somewhat comprehensive blog post about this topic as well: https://tkdodo.eu/blog/about-async-functions

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

1 Comment

Thank you, this is awesome. Helps me understand much better.

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.