I am learning react-query
and I meet some problems. I want to use the data
I get from fetching data by useQuery
, but I get data
as undefined
. Here is my code:
import React from "react";
import { useQuery } from "react-query";
import { fetchData } from "./providesData";
const Home = () => {
const {data} = useQuery("fetchData", fetchData, {
onSuccess: () => {
console.log("Get data!");
console.log(data); // undefined
}
});
return <div></div>;
};
export default Home;
But I see in react-query devtools
that the fetch is succeeded and the data
is here. So I think I do not access the data
in my onSuccess
callback properly. So how can we get access to the data
in the callback? I tried:
const query = useQuery("fetchData", fetchData, {
onSuccess: () => {
console.log("Get data!");
console.log(query.data); // undefined
}
});
but still no luck.
I read the documentation and found this:
onSuccess: (data: TData) => void
So I tried this in my code:
const {data} = useQuery("fetchData", fetchData, {
onSuccess: (data: TData) => {
console.log("Get data!");
console.log(data); // success
}
});
This time it works. But I do not understand why... And the code editor also warned me:
Type annotations can only be used in TypeScript files.ts(8010)
Can anyone show me the right way to do it? Thank you so much!
Here is a demo.
The onSuccess
callback function is called only when the data
has been retrieved from the query. Carefully notice that this data
is not the one that you're de-structuring from the useQuery
return object, but the one that has been passed to the callback on successful retrieval of data from your API. Since, it is a callback function, you don't need to check for waiting/loading cases, as it will eventually be called if your request succeeds.
In your case, the first data
variable will return undefined
as soon as the Home
component mounts, because the useQuery
call
is an asynchronous call which means that data returned from the useQuery
call will need to be resolved from a Promise
. Thus, it will not be directly available as soon as the Home
component mounts, but only after the query resolved successfully. Also, react-query useQuery
hook calls the onSuccess(data)
callback with the data received before the actual data
object(the one returned by the useQuery
hook) is set and returned from the hook.
Since useQuery
is an asynchronous call (internally), it also provides request in-flight
flags like isLoading
, isFetching
, etc. which you can use to null-check for data, errors, or any other purpose suitable.