39

I was going through the documentation of Apollo React hooks.

And saw there are two queries hooks to use for which is useQuery and useLazyQuery

I was reading this page. https://www.apollographql.com/docs/react/api/react/hooks/

Can someone explain me what is the difference between them and in which case it should be used.

Lionel George
  • 401
  • 1
  • 4
  • 7

4 Answers4

46

When useQuery is called by the component, it triggers the query subsequently.

But when useLazyQuery is called, it does not trigger the query subsequently, and instead return a function that can be used to trigger the query manually. It is explained on this page: https://www.apollographql.com/docs/react/data/queries/#manual-execution-with-uselazyquery

When React mounts and renders a component that calls the useQuery hook, Apollo Client automatically executes the specified query. But what if you want to execute a query in response to a different event, such as a user clicking a button? The useLazyQuery hook is perfect for executing queries in response to events other than component rendering. This hook acts just like useQuery, with one key 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.

Tonio
  • 4,082
  • 4
  • 35
  • 60
Kevin Moe Myint Myat
  • 1,916
  • 1
  • 10
  • 19
  • I was using "useLazyQuery" and I was sending variables from a state with the request and every time I change the state of the inputs the request executed every time the component mount, although I was using it onClick event. – Sharif Al-Hayek May 24 '21 at 06:58
  • @Sharif there should be a bug on how you use it (e.g inadvertantly execute the query function) or otherwise you may report issue https://github.com/apollographql/apollo-client/issues since this is not the case based on their documentation – Kevin Moe Myint Myat May 24 '21 at 12:45
  • 1
    you can create a new question and provide here so I can take a look? a minimal reproducible environment like codesandbox is deeply appreciated also. – Kevin Moe Myint Myat May 24 '21 at 12:47
24

Suppose you have a component where you call useQuery, then as soon as the component mounts, useQuery runs and the data is fetched from the server. But if you use useLazyQuery in that component instead of useQuery, query doesn't run and data isn't fetched when component mounts. Instead you can run the query based on your requirement, say after clicking a button. Example:

import React, { useState } from 'react';
import { useLazyQuery } from '@apollo/client';

function DelayedQuery() {
  const [dog, setDog] = useState(null);
  const [getDog, { loading, data }] = useLazyQuery(GET_DOG_PHOTO);

  if (loading) return <p>Loading ...</p>;

  if (data && data.dog) {
    setDog(data.dog);
  }

  return (
    <div>
      {dog && <img src={dog.displayImage} />}
      <button onClick={() => getDog({ variables: { breed: 'bulldog' } })}>
        Click me!
      </button>
    </div>
  );
}

Here, as soon as you click the button, then only the query runs and data is fetched and the image is displayed. But if you had used useQuery instead, before clicking the button (i.e when the component mounts), the data would have been fetched and the image would have been displayed

Animesh Timsina
  • 386
  • 2
  • 10
6

UPDATE:

https://github.com/apollographql/apollo-client/blob/main/CHANGELOG.md#improvements-due-to-brainkim-in-8875

useLazyQuery now returns a promise as of Apollo Client 3.5.0 (2021-11-08)

A.com
  • 1,466
  • 4
  • 19
  • 31
1

Something that seems not to be spoken about that I just realize is that useLazyQuery doesn't read from the cache. This is somewhat similar to calling the refetch function returned from useQuery.

David Blay
  • 527
  • 1
  • 3
  • 14
  • Yap, I was about 3 hours trying to figure out why my query is always fetching from API even with `cache-first` rule. I didn't see anything in the docs talking about it – theveloptg Jul 28 '22 at 18:53