How to Implement GraphQL in React
Implementing GraphQL in a React application allows developers to
query precise data efficiently, reducing network overhead and improving
performance. This guide provides a straightforward, step-by-step
walkthrough of setting up Apollo Client, connecting it to a GraphQL API,
and fetching data using React hooks like useQuery. By the
end of this article, you will understand how to integrate GraphQL
seamlessly into your React projects.
Step 1: Install Dependencies
To get started, you need to install Apollo Client, which is the
standard library for managing GraphQL data in React, along with the core
graphql package. Run the following command in your
terminal:
npm install @apollo/client graphqlStep 2: Initialize Apollo Client
Next, configure the Apollo Client instance. This configuration
defines the connection to your GraphQL API and sets up an in-memory
cache to store queried data. Create a file named
apolloClient.js and add the following code:
import { ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
uri: 'https://your-graphql-endpoint.com/graphql', // Replace with your GraphQL API URL
cache: new InMemoryCache(),
});
export default client;Step 3: Connect Apollo Client to React
To make the Apollo Client accessible throughout your React
application, wrap your root component with the
ApolloProvider. This component uses React’s context API to
provide the client to any nested component.
Update your index.js or main.jsx file:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { ApolloProvider } from '@apollo/client';
import client from './apolloClient';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>
);Step 4: Write and Execute a GraphQL Query
With the provider set up, you can now query data inside your React
components. Use the gql parser to define your GraphQL
query, and the useQuery hook to execute it and manage the
request’s state (loading, error, and data).
Here is an example of a component fetching a list of users:
import React from 'react';
import { useQuery, gql } from '@apollo/client';
// Define the query
const GET_USERS = gql`
query GetUsers {
users {
id
name
email
}
}
`;
function UserList() {
const { loading, error, data } = useQuery(GET_USERS);
if (loading) return <p>Loading users...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<h2>User List</h2>
<ul>
{data.users.map((user) => (
<li key={user.id}>
<strong>{user.name}</strong> - {user.email}
</li>
))}
</ul>
</div>
);
}
export default UserList;Step 5: Mutate Data (Optional)
If you need to modify data on the server, you can use the
useMutation hook. This works similarly to
useQuery but returns a function that you can call to
trigger the mutation.
import React, { useState } from 'react';
import { useMutation, gql } from '@apollo/client';
const ADD_USER = gql`
mutation AddUser($name: String!, $email: String!) {
addUser(name: $name, email: $email) {
id
name
}
}
`;
function AddUserForm() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [addUser, { loading, error }] = useMutation(ADD_USER);
const handleSubmit = (e) => {
e.preventDefault();
addUser({ variables: { name, email } });
setName('');
setEmail('');
};
return (
<form onSubmit={handleSubmit}>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Name"
required
/>
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
required
/>
<button type="submit" disabled={loading}>
{loading ? 'Adding...' : 'Add User'}
</button>
{error && <p>Error adding user: {error.message}</p>}
</form>
);
}
export default AddUserForm;