Getting the Most Out of Apollo’s useQuery

Sreevisakh
The Startup
Published in
4 min readJul 26, 2020

Apollo’s graphql solution brings a simple way to integrate with backend. The introduction of react hooks in their API really improved the overall easiness and readability of its usage. This article covers some of the common use cases of useQuery hook from Apollo.

Fetching data

Lets’ start with a simple example, Following snippet show how you can use useQuery hook to get data from the configured Graphql server. You get loading, error, data states from useQuery which you can use to show the loading state, show the error message, and actually render the data from the API, and in the example GET_BOOKS is the Graphql query

use query example

Above one is a very simple and easiest way of integrating with an api without worrying about loading states and managing error codes or parsing responses etc. Since it uses hooks it will re-render the component when there are changes.

Let’s take a look what other functionalities Apollo Graphql provide to make our life easier.

Fetching data by passing parameters

What if you don’t want to just call the api, but want to pass some conditions. For example you want books of a certain author. You can utilise the second parameter of useQuery to pass variables into the above GET_BOOKS graphql query

Fetching Data after a user action

Above example shows automatically loading data when the component renders, but that may not be the case most of the time. Mostly you end up having to fetch data after a user action, like a button click or entering data in an input field etc. Apollo Graphql provides a way to do this with the help of useLazyQuery. Here’s an example to show how it’s done.

In the above example, Book component is created to display book details. Book details are passed as props from parent component. But this component only gets name and id of the Author in the props data. So there is a “More Info” button for users who wants to take a quick look at some extra information regarding author. SO user can click on the More Info button and he component will fetch the extra information.

The component only loads more information about the author when the user clicks on “More Info” button. So first you setup the query by passing query name and variables using useLazyQuery. It is different from useQuery because on top of loading, data, error fields it also returns a function. In this example it is loadAuthorInfo. The query we setup will not be executed until we call the loadAuthorInfo . So you can call the function on when the time is right.

How about passing variables? You can do it in two ways one while setting up the query like you did before or you can pass it into the function loadAuthorInfo while calling it. Because unlike in the above example you may not know the variables to pass until after the user action. Rest everything works just like useQuery

Fetching data from a paginated API

Most applications will have to integrate with paginated api. It helps a lot if you have to load a lot of data and all of them are not required right away. There are different ways you can integrate with paginated Apis. One where you can provide select(page size) & cursor(offset) and the api will give us that amount of data or you may have an open ended pagination where you keep asking for the next page until null returns.

Above example shows the select-cursor use case, the component loads the first page with offset=0 & limit=10, and the result of that will be displayed in the page and apollo will keep the data in it state. So when the load more button is clicked you use fetchMore that is part of the useQuery return to fetch the next set of result. fetchMore is called with variables and updateQuery function. You only have to call fetchMore with the changed parameter

fetchMore will return with requested page of data. Now you need to update the state which keeps all the books. Since it is apollo state you have to tell apollo how to modify the books state to add the new result. updateQuery will take care of that. after fetchMore, apollo calls the updateQuery function with the current state and the new result and the new result will be appended to the existing result. This state change re-renders the list and we re done.

Refreshing Data

It’s good to have a refresh button near a component with changing data to let the user refresh only part of the page rather than the whole. A component that is wired with useQuery can easily do this with help of refetch functionality

when refetch is called is will execute the same query again and re-renders the page to show the new data. That’s it no more keeping tracking existing condition to reuse.

Polling for data change

Even though apollo provides subscriptions it is not recommended to use it to stay in sync with backend data. Instead you can make use of useQuery’s polling feature.

Query will be fetched every 300ms and the component will be updated on change. Just like the first example this component immediately start polling as soon as the component renders and first interval is passed. But how do you control the polling based on user actions. Apollo library provides you with two functions startPolling and stopPolling

start polling by passing an interval and stop it by stopInterval when you no longer need to poll. How about that! no more setInterval, and clearInterval in our component

Summary

These various functions available with useQuery will help you integrate with any graphql api seamlessly without any kind of manual request/response handling. state management, error handling, or complicated refetch/fetch next/poll logic. Hope this article helps you.

--

--