React Data Fetching Pattern - Part V
Tags: react, reactquery, api
Published: 2022-11-16 16:30:18

This article is a continuation of:
* [React Data Fetching Patterns - useState-useEffect](https://dev.to/francisldn/react-data-fetching-patterns-40mg)
* [React Data Fetching Pattern - Custom Hook using Context API](https://dev.to/francisldn/react-data-fetching-patterns-part-ii-10gg)
* [React Data Fetching Pattern - Redux](https://dev.to/francisldn/react-data-fetching-pattern-part-iii-584d)
* [SWR](https://dev.to/francisldn/react-data-fetching-pattern-part-iv-3mbe)

Click [here](https://github.com/francisldn/React-Data-Fetching-Patterns) to access the Github repo for the code examples discussed below.

<h3>React Query</h3>
An alternative React data fetching library that provides similar utilities as **SWR** is **React Query**.

React Query provides a hook called ``useQuery`` which accepts a query key and a callback function (``fetcher``). Similar to SWR, it also allows for integration with ``React Suspense`` API by simply including the option ``suspense: true``. If the ``fetcher`` callback requires a parameter (eg: URL), we can include this as a 2nd item in the array after the query key. ``useQuery`` will return *data*, *isLoading*, *error*, *isError* to be accessed by React components.

To allow for code reusability and avoid prop-drilling, we can create a custom hook to perform the logic of data fetching using React Query, as below. 
```
const fetcher = async(apiURL:string) => {
    try {
      const {results: data} = await getUsers(apiURL)
      return data.map((user:UserApi) => ({
          id: user.id.value,
          firstName: user.name.first,
          lastName: user.name.last,
          username: user.login.username,
          email: user.email,  
      }))
    } catch(error) {
      throw new Error('unable to fetch data')
    }
}

const useUsers = () => {
    const {isLoading, isError, data, error} = useQuery(['users',apiURL], () => fetcher(apiURL),{suspense: true})
    
    return ({
        users: data,
        isLoading,
        isError,
        error
    })
}

export default useUsers;

```
Before we can access the data in any React component, we have to wrap the ``QueryClientProvider`` around the top-level component (``<App />``).

```
import { QueryClientProvider, QueryClient } from 'react-query';

const queryClient = new QueryClient()

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  </React.StrictMode>
);

```
Within React component, we can now access the ``users`` state from ``useUsers`` hook, as below. 
```
export default function CardList() {
  const {users} = useUsers()

  return (
    <div className="grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 justify-center grid-cols-1 mt-8">
      <Suspense fallback={<Loading />}>
        {
          users.map((user:User) => (<CardItem key={user.id} user={user}/>))
        }
      </Suspense>
    </div>
  )
}
```
<h4>Pros</h4>
* Similar to **SWR**, the initial code set-up is relatively easy and it is also performant.

For more information on ``React Query``, see [here](https://tanstack.com/query/v4/docs/adapters/react-query).

I hope these article provides valuable information to you as a React developer. 

***If you like the content, please hit the like button so that it can reach more people.***