The library to handle data fetching, including retry, caching, error handling, so as to reduce the boilerplate code
Convenient to create custom hook to fetching or updating data in order to achieve separate of concern
Fresh & Stale State
Fresh: all the data must come from cache, no background refetching will be happened
Stale: data can still come from cache, but the background refetching can be happened
Default Behavior
Stale queries are refetched automatically in the background when:
New instances of the query mount
The window is refocused
The network is reconnected.
The query is optionally configured with a refetch interval.
If Query fails, will silently retry 3 times
The data of the inactive queries will be cached for 5 mins
The staleTime is 0
isLoading: Your query has no data and is currently loading for the first time
isFetching flag is not part of the internal state machine - it is an additional flag that will be true whenever a request is in-flight. You can be fetching and success, you can be fetching and error - but you cannot be loading and success at the same time.
React Query will attempt to compare the old state and the new and keep as much of the previous state as possible to prevent trivial re-rendering
Query Cancellation
Queries that unmount or become unused will be cancelled if you consume the AbortSignal or attach a cancel function to your Promise, the Promise will be cancelled (e.g. aborting the fetch)
import axios from 'axios'
const query = useQuery('todos', ({ signal }) =>
axios.get('/todos', {
// Pass the signal to `axios`
signal,
})
)
import axios from 'axios'
const query = useQuery('todos', () => {
// Create a new CancelToken source for this request
const CancelToken = axios.CancelToken
const source = CancelToken.source()
const promise = axios.get('/todos', {
// Pass the source token to your request
cancelToken: source.token,
})
// Cancel the request if React Query calls the `promise.cancel` method
promise.cancel = () => {
source.cancel('Query was cancelled by React Query')
}
return promise
})
export default function usePageUpdateMutation({
onSuccess,
...options
}: MutationOptions<AxiosResponse<Page>, AxiosError<any>, Page> = {}) {
const axios = useContext(AxiosContext);
const queryClient = useQueryClient();
return useMutation({
mutationFn: (page: Page) =>
axios.put<Page>(
`${process.env.REACT_APP_API_URL}/pages/${page.id}`,
page
),
onSuccess: (data, variables, context) => {
if (onSuccess) onSuccess(data, variables, context);
// to clear the query,
// so that the query will be loaded again and trigger isLoading
queryClient.invalidateQueries("allPageList");
queryClient.invalidateQueries(["page", variables.id]);
// set the data to the existing query directly
queryClient.setQueryData(['test', variables.id], data)
},
...options,
});
}