Data Fetching and Cache Maintenance With React-Query

Fetting data from the server and maintaining it is a very crucial issue in frontend development. In this article, on behalf of Apiumhub, we will focus on the React.js library applications and how we maintain the server state with the library called React-Query.

Into React-Query

In React, there are three types of state: the local state, which is persisted in the React components; the global state, which all components can access; and the server state which is persisted in the server most of the time and depends on both sides. To manage the server state in the frontend and sync with the backend, we need to update, cache, or re-fetch the data efficiency. Sometimes we call the backend more than necessary, and this could cause performance problems in our applications. There, the React-query library helps us to solve these performance issues, manage the cache properly and give us useful features like query cancellation, stale time configuration, infinite query re-fetting, etc.

React Query is a library that has two simple hooks which provide fetching, caching, and updating asynchronous data in React applications. It was created by open sourcer Tanner Linsley in 2019, and now it is proven that it is very useful in server state management in React applications. There are also other libraries like SWR, Apollo Client, and RTK-Query for the server state management and we can see their comparison with React query in their webpage: According to react-query page comparison, react-query is the best option objectively.

Benefits of Using React-Query

Some of the advantages that bring us React-Query are:

  • Configuring the stale, cache, retry delay time creating a queryClientConfig object.
  • Updating the stale data in the background since react-query prefetches.
  • Optimizing the requests to the backend.
  • With the refetchOnWindowFocus feature, it can re-fetch in the background when the user changes the browser tab or when they come back to the app.

And there are more of them that we will specify later.

What are the stale and cache time in the terms of React-query? Maybe we can start by explaining the five query states that React-query has in its development cycle and also which we will encounter in React-Query Dev Tools.

  • Fresh: This state is when we have the almost same data on both sides (since when we received data, possible that someone is updated at the same time) and there is no need to re-fetch it.
  • Fetting: When we initially fetch the data successfully or not.
  • Stale: Out of date data which we will need to re-fetch from the backend.
  • Inactive: This state is used to improve the speed/UX of our applications. It is previous to the deleted state.
  • The last state is the deleted state. After the data is inactive for a while (you can configure the time) it deletes from the cache.

After understanding the state of the queries we can explain the stale time and cache time. StaleTime is the duration of the transition from fresh to stale state. If we are in the fresh state we will get the data from the cache only, but if we are in the stale state we may do a background fetch. CacheTime is the duration until inactive queries will be removed from the cache. We can configure it by passing to a QueryClientProvider component from the library or passing locally in the useQuery call.

The two hooks that the library provides us are useQuery and useMutation. useQuery is used to fetch data and useMutation is used for creating, deleting, and updating the data in the server. The useQuery takes a key, a function to call the API and one object to configure this call. And all the queries will be stored in the QueryCache.

const { data: questions = {}, isLoading}} = useQuery("questions",getQuestions,{staleTime:5000,cacheTime:10});

In addition, you can send dynamic parameters in useQuery, and it will call the service when they change. For example in the code below, when “vendors” change in the component, it will call the service again.

export const useFetchQuestions = (vendors: Array<string>,element: number) =>
 useQuery([vendors], () => FormService.getDynamicQuestions(vendors, element));

The useMutation will take a mutation function to serve as required, but the mutation key will be optional. All the mutations will be stored in the MutationCache. And when we need to interact with QueryCache and MutationCache we will need to access firstly to QueryClient.

export const useDownloadFile = (filePath: string, fileId: number) =>
 useMutation(() => FormService.downloadFile(filePath, fileId));


React query is a great tool to use in React applications to manage the server state, lazy loading, pagination, and the cache maintenance. It has a simple approach and implementation. With its devtools support, it is clear to use also in more complex applications. After working with the projects which includes

React-Query saves so much boilerplate code and synchronizes the local state with the server. I hope that this article can help to explain what React-Query can contribute to your projects.


Leave a Comment