Optimistic updates and error handling in GraphQL
From the GraphQL cheat sheet · Mutations · verified Jul 2026
Optimistic updates and error handling
javascript
// Apollo Client mutation with optimistic response
import { gql, useMutation } from '@apollo/client';
const CREATE_POST = gql`
mutation CreatePost($title: String!, $content: String!) {
createPost(title: $title, content: $content) {
id
title
content
createdAt
author {
id
name
}
}
}
`;
function CreatePostForm() {
const [createPost, { data, loading, error }] = useMutation(CREATE_POST, {
// Optimistic response
optimisticResponse: {
createPost: {
__typename: 'Post',
id: 'temp-id',
title: formData.title,
content: formData.content,
createdAt: new Date().toISOString(),
author: {
__typename: 'User',
id: currentUser.id,
name: currentUser.name
}
}
},
// Update cache after mutation
update(cache, { data: { createPost } }) {
cache.modify({
fields: {
posts(existingPosts = []) {
const newPostRef = cache.writeFragment({
data: createPost,
fragment: gql`
fragment NewPost on Post {
id
title
content
createdAt
author {
id
name
}
}
`
});
return [...existingPosts, newPostRef];
}
}
});
},
// Error handling
onError(error) {
console.error('Mutation error:', error);
toast.error('Failed to create post');
},
// Success handling
onCompleted(data) {
toast.success('Post created successfully');
resetForm();
}
});
const handleSubmit = async (e) => {
e.preventDefault();
try {
await createPost({
variables: {
title: formData.title,
content: formData.content
}
});
} catch (err) {
// Error is handled by onError
}
};
return (
<form onSubmit={handleSubmit}>
{/* Form fields */}
<button type="submit" disabled={loading}>
{loading ? 'Creating...' : 'Create Post'}
</button>
{error && <p>Error: {error.message}</p>}
</form>
);
}💡 Optimistic UI updates for better UX
⚡ Rollback on error automatically
📌 Error handling with try-catch
🔥 Cache updates after mutations