Updating the cache after a Mutation

Let's think through the problem one more time:

  • We have some information about a repository in a cache that includes the number of stars it has.
  • When we star the repository, we want to see that the number of stars has been incremented by one.
  • What if we could just increment the number of stars in the cache by one? This should hopefully resolve the problem.

So, let's give this a go and update the cache after the mutation has finished:

  1. First, let's remove the refetchQueries prop we implemented in the last section.
  2. There is an update prop on the Mutation component that we can leverage to update the cache. So, let's start to implement this:
<Mutation
mutation={STAR_REPO}
update={cache => {
// Get the cached data
// update the cached data
// update our state
}}
>
...
</Mutation>
  1. So, we need to implement an arrow function that updates the cache that is available as an argument:
<Mutation
...
update={cache => {
const data: { repository: IRepo } | null = cache.readQuery({
query: GET_REPO,
variables: {
orgName: search.orgName,
repoName: search.repoName
}
});
if (data === null) {
return;
}
}}
>
...
</Mutation>

So, the cache has a readQuery function that we can use to get the cached data. If no data is found in the cache then we can exit the function without doing anything else.

  1. So, now that we have the data from the cache, we can increment the number of stars. To do this, we create a new object and spread the props from the cached repository into it and overwrite it with the incremented number of stars and the fact that the viewer has starred the repository:
update={cache => {
...
if (data === null) {
return;
}
const newData = {
...data.repository,
viewerHasStarred: true,
stargazers: {
...data.repository.stargazers,
totalCount: data.repository.stargazers.totalCount + 1
}
};
}}
  1. We can then update the cache with its writeQuery function. We pass in the query with the variable values and the new data to store in the cache:
update={cache => {
...
const newData = {
...
};
cache.writeQuery({
query: GET_REPO,
variables: {
orgName: search.orgName,
repoName: search.repoName
},
data: { repository: newData }
});
}}
  1. There's one more job to do, which is to update the repo state so that the number of stars updates immediately onscreen: 
update={cache => {
...
cache.writeQuery(...);
setRepo(newData);
}}

That should be it. If we try to star a repository in our app again, we should see that the number of stars is immediately incremented.

Caching is one of the great features that Apollo gives us out-of-the-box. The update prop on the Mutation component gives us a precise way to update our cache. The refetchQueries prop on the Mutation component is a more heavy-handed and less efficient way of forcing a cache to be updated.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.172.93