How to Update GraphQL Data in React
Updating data in a React application using GraphQL is primarily
achieved through mutations. This article provides a straightforward
guide on how to implement GraphQL mutations using the Apollo Client
library, covering how to define the mutation query, utilize the
useMutation hook, and keep the user interface in sync with
your backend database via cache updates.
Define the GraphQL Mutation
To update data, you must first define your mutation using the
gql template literal. This mutation specifies the input
arguments required for the update and the fields you want the server to
return once the operation is complete.
import { gql } from '@apollo/client';
const UPDATE_USER = gql`
mutation UpdateUser($id: ID!, $name: String!) {
updateUser(id: $id, name: $name) {
id
name
}
}
`;Execute the Mutation in a Component
Apollo Client provides the useMutation React hook to
trigger mutations. This hook returns a trigger function (which you call
to run the mutation) and an object representing the execution state,
such as loading, error, and data.
import React, { useState } from 'react';
import { useMutation } from '@apollo/client';
function UpdateUserForm({ userId }) {
const [name, setName] = useState('');
const [updateUser, { loading, error }] = useMutation(UPDATE_USER);
const handleSubmit = (e) => {
e.preventDefault();
updateUser({ variables: { id: userId, name } });
};
if (loading) return <p>Updating...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter new name"
/>
<button type="submit">Update Name</button>
</form>
);
}Keep the UI in Sync
After performing an update, you must ensure the React application reflects the changes. There are two primary methods to handle this:
1. Automatic Cache Updates
If your mutation returns the updated object along with its unique
identifier (such as id or _id) and the
modified fields, Apollo Client automatically updates the corresponding
item in its normalized cache. Any components rendering that data will
automatically re-render with the new values.
2. Refetching Queries
If the update affects data structures that Apollo cannot
automatically match (such as inserting into or deleting from lists), you
can use the refetchQueries option. This forces Apollo
Client to re-run specified queries to fetch the latest server state.
const [updateUser] = useMutation(UPDATE_USER, {
refetchQueries: [
'GetUsersList' // Name of the query to refetch
],
});