When React renders a component that calls the useQuery hook, the Apollo Client runs the query automatically. Sometimes you need to query for data on some event. To do so you can use the useLazyQuery hook.
When React renders a component that calls the useQuery hook, the Apollo Client runs the query automatically, but sometimes you need to query for data on some event. A great case is a quick search component that allows users to search for products in an eCommerce store.
There is a useLazyQuery hook that returns a query function. You can use this function wherever you want, and when you fire it, Apollo will execute a query for you.
When would you use lazy queries?
Typically custom Apollo’s hook useQuery is used when you want to query data. That kook is called when React mounts and renders the component, and Apollo Client automatically executes a query then.
What to do when you want to call a query manually thought? For instance, when a user clicks on a specific button, or if you’re running a query in a useEffect function?
Lazy queries for the rescue!
In that case, you can use the useLazyQuery hook. As I mentioned earlier, It’s pretty much the same as useQuery with one exception. When useLazyQuery is called, it does not immediately execute its associated query.
Instead, it returns a function in its result tuple that you can call whenever you’re ready to execute the query.
On the other hand, the useLazyQuery hook is ideal for executing queries in response to different events, such as user actions. Whenever the useLazyQuery command occurs, the application will not immediately run any queries. You need to trigger a query manually.
Take a look at the example:
How useful is that?
Refetch function
The useQuery returns data, and the useLazyQuery returns data as well. Those hooks return cached data or server data. It doesn’t matter, they return the requested data and the component renders that data. The default behavior of the useQuery hook is to perform a query when the component re renders. Lazy query allows performing a query on demand.
Moreover, an additional mechanism allows to refetch queries on demand to particular user action. Take a look at the example:
You can bind refetch function in the JSX code like this:
As you can see, you can pass new variables to the function.
Practical usage
Let’s use that knowledge about lazy queries and implement a QuickSearch component in the React app.
QuickSearch component
Create a quick search component with the following content:
I define two states there: isValid and searchQuery, and I pass them to the child component. I check the length of the value entered by a user in the search input, and if the length is higher than 3, I send the query.
Quick Search Suggestion component
Create a new component called QuickSearchSuggestion with the following content:
I use a custom hook there: useQuickSearchSuggestion. That hook’s responsibility is to provide data and business logic for the component. I am going to define that hook in the next step.
To finish the QuickSearchSuggestion, I create a CSS module QuickSearchSuggestions.module.css with the following styles:
use Quick Search Suggestions custom hook
As you can see, I’ve defined a lazy query that returns the fetchSuggestions function.
Then I use that function in effect. Before calling, I check if the search query is valid and update the isOpen flag. The fetchSugestions query function takes graphql variables (searchQuery), fetch the data, and returns it to the react component.
graphQL query
The last thing we need to do is create a graphQL query used by the useQuickSearchSuggestions hook.
Summary
It looks like the Quick Search functionality works good:
So to execute GraphQL queries using Apollo GraphQL client, you can choose between two custom apollo react hooks:
-
useQuery
-
useLazyQuery
What is the difference between useQuery hook and useLazyQuery?
When using useLazyQuery, it does not perform the associated query. Instead, the function returns query functions in the result tuples called when the query is executed.
The useLazyQery hook is perfect when you, for example, need to fetch data for the GraphQL server on user action, user clicking, or typing.
Apollo React Hooks and cached data
Apollo client provides a cache mechanism called InMemoryCache. Thanks to that, the apollo cache query results in memory. Of course, Apollo react hooks supports that cache. You can set the default fetch policy globally and locally on each query.
Handling GraphQL errors
Lazy query error handling is pretty the same as when you use the useQuery hook. Please follow this article if you want to get more about GraphQL errors.