How to update Apollo Cache via React Hooks after calling REST api
Apollo local cache (InMemoryCache) works super great, but recently I have a problem with it, the UI re-renders when updating the cache after a GraphQL mutation, but not after I calling a traditional REST api and try to update the cache directly. The intention is simple, I want to update the local cache directly and re-render the UI. Let’s see how to solve it.
1. 2 cases in terms of updating the cache
First thing first, all the below discussion are based on the fact that you try to update the cache not in the context of GraphQL, if you just want to update the cache after a GraphQL mutation, there are a lot of resources online, and it just works.
- The object is simple, so you can just update the cache by yourself.
- A very complex update which involves a lot of nested update, you’d rather just calling the endpoint again.
2. Handle case 1
The writeData
and writeQuery
won’t work here since you are not dealing with GraphQL.
You need updateQuery
, this is how you do it.
1 | import { useApolloClient } from "@apollo/react-hooks"; |
The updateQuery
function you get from the useQuery
hook will give you the previous data, and you just return a new data if something has changed.
Unlike the cache.writeQuery
where you can mutate the data
directly, here you have to return a new object to maintain the immutability.
And since you are handling everything by yourself, remember to add the __typename
to your item, so Apollo can know how to match the new data.
No extra network request, the UI will be re-rendered.
According to the document:
A function that allows you to update the query’s result in the cache outside the context of a fetch, mutation, or subscription
3. Handle case 2
When the data structure is complex or there will be some side-effects happened not in your app, you can use the following method to get the latest update.
1 | import { useApolloClient } from "@apollo/react-hooks"; |
via calling the refetch()
, the UI who uses the same query, in this case: GET_USERS_QUERY
, will be re-rendered.
If you have any variables for the GraphQL query, refetch()
takes it as the 1st parameter.
One thing to note is that refetch()
will invoke the network request.
4. End
That is the end. Hope it helps.
Thanks for reading!
Follow me (albertgao) on twitter, if you want to hear more about my interesting ideas.