DEV Community

Victor De Grandis
Victor De Grandis

Posted on • Edited on

How to use React Query on Nextjs

Introduction

React query is a tool for creating hooks for fetching, caching and updating asynchronous data repository.

Motivation

Fetching data from your backend is one of the most performance killers features of any frontend, and it really helps to keep a copy of the fetched data in the browser, but it's not always possible, or convenient to build a Redux store, so react-query is a good alternative for managing API results without having to do a lot of work for it, and without having to fetch it again every time you need it.
With react-query, you have a shared source for all components that use that data, with a cache and mutations for updating the state across your application.

As their docs say:

React Query replaces the boilerplate code and related wiring used to manage cache data in your client state and replaces it with just a few lines of code.

You can check their motivation on their page

Usage

  • First, you have to configure the provider QueryClientProvider like this:
// _app.tsx

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

export default function App({Component, pageProps}) {
  const queryClientRef = useRef<QueryClient>();

  if (!queryClientRef.current) {
    queryClientRef.current = new QueryClient();
  }

  return (
    <React.Fragment>
      <Head>
        ...
      </Head>
      <QueryClientProvider client={queryClientRef.current}>
        <Component {...pageProps} />
        <ReactQueryDevtools initialIsOpen={false} />
      </QueryClientProvider>
    </React.Fragment>
  );
}
Enter fullscreen mode Exit fullscreen mode

If you don't know what a provider is, visit the react docs.

ReactQueryDevtools is an integrated tool from react-query that helps tremendously with inspecting and debugging queries.

  • Secondly, you have to make a service, for example at /lib/services/getClientsService.ts
// /lib/hooks/getClientsService.ts

export async function getClients(): Promise<NetworkResponse<Client>> {
  return axios.get(`/api/clients`).then(response => response.data);
}
Enter fullscreen mode Exit fullscreen mode
  • And finally, a hook for consuming the service and giving react query the retry options:
// /lib/hooks/useClients.ts

export function useClients() {
  const { data, status } = useQuery<NetworkResponse<Client>, AxiosError>(
    `/clients`,
    () => getClients(),
    {
      retry: true,
      refetchOnWindowFocus: false,
      refetchOnReconnect: false
    }
  );

  return { data: data, status };
}
Enter fullscreen mode Exit fullscreen mode

Now you're good to go using the hook in every component necessary, like so:


export default function Clients() {
  const { clients } = useClients()

  return (
    <>
      <div className="flex flex-wrap mt-4">
        <div className="w-full mb-12 px-4 h-full">
          {clients && clients.length > 0 ? (
            <ClientsTable clients={clients} />
          ) : (
            <Spinner />
          )}
        </div>
      </div>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

And there you have it, it isn't hard at all to build and it has a very good performance.

Have a good day :).

Top comments (0)