Mutations
In the previous tutorial, we've discussed how to fetch data from our backend with Apollo Client, sequentially, in this tutorial, we will learn how to update that data with mutations. This tutorial demonstrates how to send updates to your GraphQL server with the useMutation hook. We'll also learn how to update the Apollo Client cache after executing a mutation.
Prerequisites
This tutorial assumes you're familiar with building basic GraphQL mutations. If you need a refresher, we recommend you check our previous tutorials. We also assume that you've already set up Apollo Client and have wrapped your React app in an ApolloProvider component.
Executing a mutation
The useMutation React hook is the primary API for executing mutations in an Apollo application. To run a mutation, you first call useMutation within a React component and pass it a GraphQL string that represents the mutation. When your component renders, useMutation returns a tuple that includes:
- A mutate function that you can call at any time to execute the mutation
- An object with fields that represent the current status of the mutation's execution
Let's look at an example. First, we'll create a GraphQL mutation named ADD_TODO, which represents adding an item to a to-do list. Remember to wrap GraphQL strings in the gql function to parse them into query documents:
//index.js
import gql from 'graphql-tag';
import {useMutation} from '@apollo/react-hooks';
const ADD_TODO = gql`
mutation AddTodo($type: String!) {
addTodo(type: $type) {
id
type
}
}
`;
Next, we'll create a component named AddTodo that represents the submission form for the to-do list. Inside it, we'll pass our ADD_TODO mutation to the useMutation hook:
//index.js
function AddTodo() {
let input;
const [addTodo, { data }] = useMutation(ADD_TODO);
return (
<div>
<form
onSubmit={e => {
e.preventDefault();
addTodo({ variables: { type: input.value } });
input.value = '';
}}
>
<input
ref={node => {
input = node;
}}
/>
<button type="submit">Add Todo</button>
</form>
</div>
);
}
Calling the mutate function
The useMutation hook does not automatically execute the mutation you pass it when the component renders. Instead, it returns a tuple with a mutate function in its first position (which we assign to addTodo in the example above). You then call the mutate function at any time to instruct Apollo Client to execute the mutation. In the example above, we call addTodo when the user submits the form.
Providing options
Both useMutation itself and the mutate function accept options. Options provided to a mutate function override any options you previously provided in useMutation. In the example above, we provide the variables option to addTodo, which enables us to specify any GraphQL variables that the mutation requires.
Tracking mutation status
In addition to a mutate function, the useMutation hook returns an object that represents the current state of the mutation's execution. The fields of this include booleans that indicate whether the mutate function has been called yet, and whether the mutation's result is currently loading.
Updating the cache after a mutation
When you execute a mutation, you modify back-end data. If that data is also present in your Apollo Client cache, you might need to update your cache to reflect the result of the mutation. This depends on whether the mutation updates a single existing entity.
Updating a single existing entity
If a mutation updates a single existing entity, Apollo Client can automatically update that entity's value in its cache when the mutation returns. To do so, the mutation must return the id of the modified entity, along with the values of the fields that were modified. Conveniently, mutations do this by default in Apollo Client.
Let's look at an example that enables us to modify the value of any existing item in our to-do list:
const UPDATE_TODO = gql`
mutation UpdateTodo($id: String!, $type: String!) {
updateTodo(id: $id, type: $type) {
id
type
}
}
`;
function Todos() {
const { loading, error, data } = useQuery(GET_TODOS);
const [updateTodo] = useMutation(UPDATE_TODO);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return data.todos.map(({ id, type }) => {
let input;
return (
<div key={id}>
<p>{type}</p>
<form
onSubmit={e => {
e.preventDefault();
updateTodo({ variables: { id, type: input.value } });
input.value = '';
}}
>
<input
ref={node => {
input = node;
}}
/>
<button type="submit">Update Todo</button>
</form>
</div>
);
});
}
If you execute the UPDATE_TODO mutation using this component, the mutation returns both the id of the modified to-do item and the item's new type. Because Apollo Client caches entities by id, it knows how to automatically update the corresponding entity in its cache. The application's UI also updates immediately to reflect changes in the cache.
Previous:
Queries
Next:
Local state management
It will be nice if you may share this link in any developer community or anywhere else, from where other developers may find this content. Thanks.
https://www.w3resource.com/apollo-graphql/mutations.php
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics