For this question, the following schema is a simplified description of the situation:
type CartItem {
id:ID!
description:String!
qty:Int
price:Float
}
type Cart {
createdAt:DateTime
updatedAt:Datetime
items:[CartItems!]
}
type Mutation {
removeCartItem(itemId:ID!):Cart
}
(Again, this is providing the most basic use case I can think of for this question.)
When removing an item from the cart, it is expected that the Cart value stored in cache will reflect the new updated state, thus the entire cart is returned.
import { useQuery, useMutation, gql } from '@apollo/client';
const CART_QUERY = gql`query GetCart {
cart {
createdAt
updatedAt
items {
id
description
qty
price
}
}
}`;
const REMOVE_ITEM_MUTATION = gql`mutation RemoveCartItem($itemId:ID!) {
removeCartItem(itemId:$itemId) {
createdAt
updatedAt
items {
id
description
qty
price
}
}
}`;
function CartDisplay() {
const { loading, data:{ cart } } = useQuery(CART_QUERY);
const [ removeCartItem ] = useMutation(REMOVE_ITEM_MUTATION);
const handleDeleteItem = itemId => {
removeCartItem({ variables: { itemId } });
}
return cart?.items?.length ? cart.items.map(cartItem => (
<CartItemCard key={ cardItem.id }
cardItem={ cardItem }
onDelete={ handleDeleteItem }
/>
)) : (
<div>No items in cart</div>
);
}
Because GraphQL updates the Cart when it is mutated, the useQuery triggers a component update with the updated value. However, the entire Cart is fetched!
How can the mutation return only the parts that should be updated, in this case, tell the cache to remove the item from the array? Do I have to manually update the cache when the mutation is successful? What about optimistic updates?
In other words, what should the mutation return in order to only update what needs to be updated and not the entire graph data; is that even possible?