GraphQL with Apollo Client in React
Apollo Client is a popular library that enables you to interact with GraphQL APIs in a more efficient and declarative way. It simplifies data fetching, caching, and state management for React applications. With Apollo Client, you can easily send GraphQL queries and mutations to a GraphQL server and manage the data in your app.
Apollo Client works seamlessly with GraphQL, providing a powerful set of tools to manage data fetching, caching, error handling, and more. Below, we'll explore how to integrate Apollo Client with a React application, perform GraphQL operations, and manage state.
1. What is GraphQL?
GraphQL is a query language for APIs and a runtime for executing those queries with your data. It allows you to request only the data you need and get responses in a predictable structure.
Unlike REST, where you make multiple requests to different endpoints for various pieces of data, GraphQL allows you to send a single query that can retrieve multiple types of data from different sources in one go.
2. Installing Apollo Client
To use Apollo Client with React, you'll need to install the necessary dependencies. First, install Apollo Client and GraphQL:
npm install @apollo/client graphql
3. Setting Up Apollo Client
To set up Apollo Client, you'll need to create an Apollo Client instance and connect it to a GraphQL endpoint. You'll also need to wrap your React app with the ApolloProvider
component to make the Apollo Client instance available throughout the app.
import React from 'react';
import ReactDOM from 'react-dom';
import { ApolloProvider, InMemoryCache } from '@apollo/client';
import App from './App';
// Create an Apollo Client instance
const client = new ApolloClient({
uri: 'https://your-graphql-endpoint.com/graphql', // Your GraphQL endpoint
cache: new InMemoryCache(), // Apollo Client's cache implementation
});
// Wrap your React app with ApolloProvider and pass the client
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>,
document.getElementById('root')
);
-
Apollo Client is created with the
uri
(the URL of your GraphQL server) and acache
(which usesInMemoryCache
to store and manage cached data).
4. Making GraphQL Queries with Apollo Client
Apollo Client makes it easy to execute GraphQL queries in React using the useQuery
hook. The hook returns an object with properties like data
, loading
, and error
.
Here’s an example of how to use useQuery
to fetch data from a GraphQL server.
import React from 'react';
import { useQuery, gql } from '@apollo/client';
// Define a GraphQL query
const GET_BOOKS_QUERY = gql`
query GetBooks {
books {
id
title
author
}
}
`;
const BooksList = () => {
// Execute the query using useQuery hook
const { loading, error, data } = useQuery(GET_BOOKS_QUERY);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<h1>Books List</h1>
<ul>
{data.books.map((book) => (
<li key={book.id}>
{book.title} by {book.author}
</li>
))}
</ul>
</div>
);
};
export default BooksList;
-
gql
: A template literal provided by Apollo Client to define GraphQL queries or mutations. -
useQuery
: A hook provided by Apollo Client that executes the specified query and returns thedata
,loading
, anderror
states.
5. Making GraphQL Mutations with Apollo Client
In addition to fetching data, Apollo Client also provides the ability to send GraphQL mutations using the useMutation
hook. Mutations are used to modify data on the server (e.g., creating, updating, or deleting records).
Here’s an example of using useMutation
to add a new book.
import React, { useState } from 'react';
import { useMutation, gql } from '@apollo/client';
// Define a GraphQL mutation
const ADD_BOOK_MUTATION = gql`
mutation AddBook($title: String!, $author: String!) {
addBook(title: $title, author: $author) {
id
title
author
}
}
`;
const AddBook = () => {
const [title, setTitle] = useState('');
const [author, setAuthor] = useState('');
const [addBook, { loading, error }] = useMutation(ADD_BOOK_MUTATION, {
variables: { title, author },
onCompleted: () => {
setTitle('');
setAuthor('');
},
});
const handleSubmit = (e) => {
e.preventDefault();
addBook();
};
return (
<div>
<h2>Add a New Book</h2>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Title"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<input
type="text"
placeholder="Author"
value={author}
onChange={(e) => setAuthor(e.target.value)}
/>
<button type="submit" disabled={loading}>
{loading ? 'Adding...' : 'Add Book'}
</button>
</form>
{error && <div>Error: {error.message}</div>}
</div>
);
};
export default AddBook;
-
useMutation
: A hook for sending GraphQL mutations to the server. It takes the mutation and optionally an object with variables and options (likeonCompleted
oronError
). -
Variables: You can pass dynamic variables to mutations to make them more flexible (like
title
andauthor
in the example).
6. Caching with Apollo Client
Apollo Client uses an in-memory cache to store the results of your queries. This means that once data is fetched, it is cached, and subsequent requests for the same data are served from the cache, improving performance.
For instance, if the user visits the same page again, the data will be loaded instantly from the cache.
To enable cache updates after a mutation, you can use refetchQueries
or update
options:
const [addBook] = useMutation(ADD_BOOK_MUTATION, {
variables: { title, author },
refetchQueries: [{ query: GET_BOOKS_QUERY }], // Re-fetch books after mutation
});
7. Error Handling and Optimistic UI
Apollo Client supports optimistic UI updates, where you can immediately update the UI to reflect the changes even before the server responds.
Example of using optimisticResponse
for mutations:
const [addBook] = useMutation(ADD_BOOK_MUTATION, {
optimisticResponse: {
__typename: 'Mutation',
addBook: {
__typename: 'Book',
id: 'temp-id',
title: 'New Book',
author: 'Unknown',
},
},
update(cache, { data: { addBook } }) {
const { books } = cache.readQuery({ query: GET_BOOKS_QUERY });
cache.writeQuery({
query: GET_BOOKS_QUERY,
data: { books: books.concat([addBook]) },
});
},
});
- Optimistic Response: Apollo Client immediately updates the UI with the expected response, improving the user experience.
- Cache Update: After the mutation completes, you can update the cache manually to ensure it reflects the new data.
8. Conclusion
Apollo Client simplifies working with GraphQL in React applications by providing powerful tools for querying, mutating, caching, and managing data. With the use of hooks like useQuery
and useMutation
, Apollo Client integrates seamlessly into functional React components and helps maintain an efficient, declarative approach to data management.
Top comments (0)