Reputation: 3439
Suppose I have a react application with these features on a single page: New books, Books by author xyz, Create new book
Now suppose I create a new book by author xyz. The page is updated in two places, there is one more new book, and there is one more book by author xyz.
How do apollo-react and relay differ in their approach to solving this issue? How do they solve this issue? Most of the examples I have seen only show rudimentary mutations
Upvotes: 3
Views: 306
Reputation: 6147
Here's how to solve this in Apollo.
Let's say we're working with the following query for this part of the UI:
query AllBooks {
newBooks {
title
author { name }
}
author(id: "stubailo") {
id
books {
title
}
}
}
Of course in reality you might have some pagination, variables, etc. But for this example I'll just use something simple.
Now, let's write a mutation to create that new book, it might look like:
mutation CreateBook($book: BookInput!) {
createBook(book: $book) {
title
author { name }
}
}
Now, we have two main options in Apollo to handle this.
First option is to simply refetch the entire query:
client.mutate(CreateBookMutation, {
variables: { book: newBook },
refetchQueries: [ { query: AllBooksQuery } ],
})
This is simple and effective, but might not be efficient if for some reason that query result is super expensive to calculate.
The second option is to incorporate the result by updating the entire query result. You can use updateQueries, but the newest way recently introduced is to use the update
callback on the mutation with the new imperative write API:
client.mutate(CreateBookMutation, {
variables: { book: newBook },
update: (proxy, mutationResult) => {
// Get data we want to update, in the shape of the query
const data = proxy.readQuery({ query: AllBooksQuery });
// It's fine to mutate here since this is a copy of the data
data.newBooks.push(mutationResult.createBook);
data.author.books.push(mutationResult.createBook);
// Write the query back to the store with the new items
proxy.writeQuery({ query: AllBooksQuery, data });
},
})
As you can see, with GraphQL it's not much easier than in other data loading solutions to keep the UI updated. The API doesn't give you much information about where the new data should go, so you have to tell Apollo what to do with it.
Notably, this is only the case for adding and deleting items - updating existing items works automatically.
Upvotes: 2