How to Handle Loading State in Apollo Client Correctly
loading property returned from the useQuery hook or query result. Display a loading indicator (like a spinner or message) while loading is true, and show data only after loading completes.Why This Happens
When you run a query with Apollo Client, the data is fetched asynchronously. If you try to render data immediately without checking if it is still loading, your UI may show empty or undefined data, causing confusion or errors.
import { useQuery, gql } from '@apollo/client'; const GET_USERS = gql` query GetUsers { users { id name } } `; function UsersList() { const { data } = useQuery(GET_USERS); return ( <ul> {data?.users.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> ); }
The Fix
Check the loading property before rendering data. Show a loading message or spinner while data is loading. Only render the data list after loading is false and data exists.
import { useQuery, gql } from '@apollo/client'; const GET_USERS = gql` query GetUsers { users { id name } } `; function UsersList() { const { loading, error, data } = useQuery(GET_USERS); if (loading) return <p>Loading users...</p>; if (error) return <p>Error loading users.</p>; return ( <ul> {data.users.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> ); }
Prevention
Always destructure and check loading and error from Apollo's useQuery hook before accessing data. Use conditional rendering to avoid runtime errors. Consider creating reusable loading and error components for consistency.
Use linting rules or code reviews to ensure loading states are handled. Testing UI with loading and error states helps catch issues early.
Related Errors
Common related errors include:
- Accessing data before it loads: Causes
TypeErrorbecause data is undefined. - Not handling errors: UI may break or show nothing if the query fails.
- Ignoring network status: Leads to poor user experience without feedback.
Quick fixes: Always check loading and error before rendering data.