Data Fetching Using React Query. Why prefer React Query over Redux?
By: Iamsonika
Tags: JavaScript, React, React Query, Axios React, Redux

I’ve always believed there must be a better way to do the same with React JS. Although I have been using Redux to handle data fetching in projects.

Why React Query?

In redux, each fetch operation requires the developer to create:

three actions (fetch request, succeeded, failed)

three reducers (fetch request, succeeded, failed)

one middleware (usually redux-saga or redux-thunk)

Writing all this code takes a lot of time, even for a simple API call.

Redux process for a fetch operation:

Dispatch an Action fetchSomething() from within the Component This Action hits the Reducer which will update the store with something like isLoading: true The Component re-renders and displays a loader In the meanwhile, the Action hits the Middleware which takes care of calling the API The API returns the response to the Middleware, which dispatches another Action: fetchSomethingSucceeded() when succeeded, or fetchSomethingFailed() when failed The succeeded/failed Action hits the Reducer, which updates the store Finally, the response is back to the Component (optionally through a memoized selector) which will show the data

Every fetch operation performed by Redux has to save its loading and response statuses in the Redux store. This is just Over usage of Redux store.

However, the purpose of this article is to provide you a better alternative to Redux.

React Query

React Query is one of the best libraries for managing server states.

React Query is specifically designed to manage any asynchronous state that you get from outside of your app: server-state, API state that is not local client state.

In general Global store, can have a Client state and Server state

For the server state, we can use React Query.

we can use React Query. For the client state, we can React Hooks like useContext and userReducer or redux.

The library exports a Hook called useQuery that accepts two arguments:

useQuery('repoData', fetcher)

A unique ID of your choice, This is being used to save the result of the API in the queryCache , a smart local cache managed by React Query. This cache is also accessible through the library’s API. For example, repoData is an id A function that calls the API and returns a Promise. Example, fetcher

import { QueryClient, QueryClientProvider, useQuery } from 'react-query'; const queryClient = new QueryClient(); export default function App() { return ( <QueryClientProvider client={queryClient}> <Example /> </QueryClientProvider> ) } const fetcher = () => { return fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res => res.json()); } const Example = () => { const { isLoading, error, data } = useQuery('repoData', fetcher)

if (isLoading) return 'Loading...' if (error) return 'An error has occurred: ' + error.message return ( <div> <h1>{data.name}</h1> <p>{data.description}</p> <strong> {data.subscribers_count}</strong>{' '} <strong> {data.stargazers_count}</strong>{' '} <strong> {data.forks_count}</strong> </div> )

}

Tips

Never use useQuery inside the Component. Instead, wrap it into a custom hook. This will keep your Component abstracted from the library and increase decoupling, as well as making the query reusable and testable.

Are there any downsides?

Debugging

Redux DevTools are really powerful and well-integrated with the browser, and even if React Query provides DevTools as well, they are not comparable for the time being. The library is anyway growing really fast, and new features are being implemented regularly.

Conclusions