Bird
Raised Fist0
GraphQLquery~10 mins

useQuery hook in GraphQL - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - useQuery hook
Component Renders
useQuery Hook Called
Send GraphQL Query Request
Wait for Response
Loading State True
Display Loading
Response Received
Update Data & Loading State
Component Re-renders with Data
The useQuery hook runs a GraphQL query when the component renders, manages loading state, and updates the component with the fetched data.
Execution Sample
GraphQL
const { loading, error, data } = useQuery(GET_USERS);

if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;

return <ul>{data.users.map(u => <li key={u.name}>{u.name}</li>)}</ul>;
This code fetches users with useQuery, shows loading or error messages, and displays user names when data arrives.
Execution Table
StepActionloadingerrordataComponent Output
1Component renders, useQuery calledtruenullnull'Loading...' displayed
2GraphQL request senttruenullnull'Loading...' displayed
3Response received with datafalsenull{users: [{name: 'Alice'}, {name: 'Bob'}]}User list rendered
4Component re-renders with datafalsenull{users: [{name: 'Alice'}, {name: 'Bob'}]}<ul><li>Alice</li><li>Bob</li></ul>
💡 Loading becomes false and data is set, so component renders user list.
Variable Tracker
VariableStartAfter Step 1After Step 3Final
loadingundefinedtruefalsefalse
errorundefinednullnullnull
dataundefinednull{users: [{name: 'Alice'}, {name: 'Bob'}]}{users: [{name: 'Alice'}, {name: 'Bob'}]}
Key Moments - 3 Insights
Why does the component show 'Loading...' first before any data appears?
At Step 1 and 2 in the execution_table, loading is true and data is null, so the component returns the loading message until data arrives.
What happens if the GraphQL query fails?
If an error occurs, error becomes non-null and loading becomes false, so the component would display the error message instead of data, similar to Step 3 but with error set.
Why does the component re-render after data is received?
At Step 3, when data is set and loading is false, React triggers a re-render so the component can display the fetched data, as shown in Step 4.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of 'loading' at Step 3?
Afalse
Bnull
Ctrue
Dundefined
💡 Hint
Check the 'loading' column in the execution_table at Step 3.
At which step does the component first display the user list?
AStep 1
BStep 4
CStep 3
DStep 2
💡 Hint
Look at the 'Component Output' column to see when the user list is rendered.
If the query returned an error, which variable would change from null to a value?
Aloading
Bdata
Cerror
DComponent Output
💡 Hint
Refer to the 'error' variable in the variable_tracker and key_moments about error handling.
Concept Snapshot
useQuery hook syntax:
const { loading, error, data } = useQuery(YOUR_QUERY);

- Runs query on component render
- loading true while fetching
- error set if query fails
- data holds fetched results

Use loading and error to show messages,
then render data when ready.
Full Transcript
The useQuery hook is called when a component renders. It sends a GraphQL query request and sets loading to true. While waiting, the component can show a loading message. When the response arrives, loading becomes false and data is set with the results. The component re-renders to display the data. If an error occurs, error is set and can be shown instead. This flow helps manage asynchronous data fetching in React components simply and clearly.

Practice

(1/5)
1. What does the useQuery hook in GraphQL primarily do inside a React component?
easy
A. Fetches data from a GraphQL server and provides loading and error states
B. Updates data on the GraphQL server
C. Deletes data from the GraphQL server
D. Creates a new GraphQL schema

Solution

  1. Step 1: Understand the purpose of useQuery

    The useQuery hook is designed to run a GraphQL query and fetch data.
  2. Step 2: Recognize the states it provides

    It also provides loading and error states to manage UI feedback during data fetching.
  3. Final Answer:

    Fetches data from a GraphQL server and provides loading and error states -> Option A
  4. Quick Check:

    useQuery fetches data = A [OK]
Hint: useQuery fetches data and manages loading/error states [OK]
Common Mistakes:
  • Confusing useQuery with mutation hooks
  • Thinking useQuery updates or deletes data
  • Assuming useQuery creates schemas
2. Which of the following is the correct syntax to use the useQuery hook with a query named GET_USERS?
easy
A. useQuery(GET_USERS).then(response => ...);
B. const { data, loading, error } = useQuery(GET_USERS);
C. const data = useQuery(GET_USERS);
D. const { data, error } = useQuery(GET_USERS, loading);

Solution

  1. Step 1: Recall the useQuery return structure

    The useQuery hook returns an object with data, loading, and error properties.
  2. Step 2: Match the correct destructuring syntax

    const { data, loading, error } = useQuery(GET_USERS); correctly destructures these properties from the hook call.
  3. Final Answer:

    const { data, loading, error } = useQuery(GET_USERS); -> Option B
  4. Quick Check:

    Destructure data, loading, error = C [OK]
Hint: Destructure data, loading, error from useQuery call [OK]
Common Mistakes:
  • Not destructuring loading state
  • Using promises with useQuery (it's a hook)
  • Passing loading as argument
3. Given this code snippet:
const { data, loading, error } = useQuery(GET_POSTS);
if (loading) return 'Loading...';
if (error) return 'Error!';
return data.posts.length;

What will be the output if data.posts contains 5 posts?
medium
A. 5
B. 'Error!'
C. undefined
D. 'Loading...'

Solution

  1. Step 1: Check loading and error conditions

    The code returns 'Loading...' if loading is true and 'Error!' if error exists. Since data.posts has 5 posts, loading is false and error is null.
  2. Step 2: Return the length of posts array

    With no loading or error, the code returns data.posts.length, which is 5.
  3. Final Answer:

    5 -> Option A
  4. Quick Check:

    data.posts.length = 5 [OK]
Hint: Check loading/error first, then return data length [OK]
Common Mistakes:
  • Ignoring loading state and expecting data immediately
  • Confusing error with data
  • Returning undefined if data is not checked
4. Identify the error in this code using useQuery:
const { data, loading, error } = useQuery(GET_COMMENTS);
if (loading) return ;
if (error) return

Error occurred

;
return data.comments.map(c => <p>{c.text}</p>);
medium
A. The map function should use curly braces instead of parentheses
B. The component returns JSX before checking loading
C. The query name GET_COMMENTS is not imported
D. No error; code is correct

Solution

  1. Step 1: Check for common mistakes in useQuery usage

    The code uses GET_COMMENTS but does not show it being imported or defined, which is required.
  2. Step 2: Verify JSX and map usage

    The JSX and map syntax are correct; returning JSX conditionally is valid.
  3. Final Answer:

    The query name GET_COMMENTS is not imported -> Option C
  4. Quick Check:

    Missing query import = A [OK]
Hint: Always import your GraphQL queries before useQuery [OK]
Common Mistakes:
  • Forgetting to import the query
  • Returning JSX before loading check
  • Incorrect map syntax for JSX
5. You want to fetch a list of users but only display them after the data is fully loaded. Which pattern correctly uses useQuery to achieve this?
hard
A. const { data } = useQuery(GET_USERS); if (!loading) return data.users.map(u => u.name); else return 'Loading...';
B. const { loading } = useQuery(GET_USERS); if (loading) return data.users; else return 'Loading...';
C. const { data } = useQuery(GET_USERS); return data.users.map(u => u.name);
D. const { data, loading } = useQuery(GET_USERS); if (loading) return 'Loading...'; return data.users.map(u => u.name);

Solution

  1. Step 1: Understand loading state usage

    We must show 'Loading...' while data is loading, so check if loading is true first.
  2. Step 2: Return user list only after loading is false

    const { data, loading } = useQuery(GET_USERS); if (loading) return 'Loading...'; return data.users.map(u => u.name); correctly returns 'Loading...' if loading is true, else maps over data.users.
  3. Final Answer:

    const { data, loading } = useQuery(GET_USERS); if (loading) return 'Loading...'; return data.users.map(u => u.name); -> Option D
  4. Quick Check:

    Check loading first, then return data = B [OK]
Hint: Always check loading before accessing data [OK]
Common Mistakes:
  • Accessing data before loading is false
  • Returning data when loading is true
  • Ignoring loading state completely