How to Update Relay Cache

Danny Kim
dooboolab
Published in
3 min readJan 31, 2021
Photo by Alina Grubnyak on Unsplash

This article covers how to manipulate records inside Relay cache (a.k.a. Relay store). Although Relay can take care of great amount of state management by itself, sometimes developers have to tell Relay what to do. In order to do that efficiently, we need to know how Relay manages its cache and how we can interact with the cache.

What Relay Cache Looks Like

Relay stores its cache as a graph of records. Each record is identified by its unique ID, and a record can have scalar fields and “links” to other records.

For example, look at this GraphQL schema:

A User record has an id field and an email field which are scalars. Also, it has a list of Post records, and we call these “linked records”.

So for example, if we want to access an Post record inside Relay cache, we have two options:

  1. Access it directly by its ID.
    store.get('xyzpq9999')
  2. Access the user which is linked to the Post record of our interest, then follow the link.
    store.get(‘abcde5656’).getLinkedRecord(‘posts’)[1]

We can freely modify scalar values or links as long as we can access the cached records. I will discuss the API specifics later in this article.

How to Update Relay Cache

There are two ways to update Relay cache.

  1. Fetch the updated record from server.
  2. Use Relay updater function.

Approach 1: Fetch the Updated Record

The first approach is easier and cleaner. If server can response with the updated record after mutation, Relay can automatically update the cache accordingly. Look at this GraphQL mutation:

It is a simple mutation that updates the title of a Post. When successful, server will return the updated version of Post. Relay will use this response to update its cache, so there is no extra effort required for us.

Just make sure to request id and title field so that Relay can process the response and update cache.

Approach 2: Updater Function

Receiving the updated value immediately as a response is nice, but sometimes we cannot change APIs to suit our needs. This is where we need to manually modify Relay cache using updater function. I will cover the basics in this article, but you might want to check out Relay’s official documentation on this topic.

Consider this mutation:

deletePostContent mutation does not respond with the updated Post record; therefore, Relay will not update its cache automatically. Although we do not have the updated record, we know that the content field will be null after successful deletePostContent. Here’s how you update cache manually using updater function:

In this case, finding the Post record was easy because we knew its ID. store.get method returns a proxy to the record if it exists. Proxy is how we mainly interact with Relay cache, so it is a good idea to get familiar with its API (Relay Store API). Here are a few useful methods of RecordProxy :

  • getValue : Gets the value of a scalar field.
  • setValue : Sets the value of a scalar field.
  • getLinkedRecord : If a field is linked to another record, get RecordProxy of the linked record.
  • setLinkedRecord : Link the given field to the given record. If there is an existing linked record, the original linked record is unlinked.
  • getLinkedRecords : gets a list of linked records (e.g. User.posts ).

Alternatives to Cache Update

Maybe your issue can be resolved without updating Relay cache. Consider these alternatives before writing your updater function.

Cache Invalidation

We can invalidate individual records using RecordProxy.invalidateRecord method. Calling this method will mark the Record as “stale” and force Relay not to re-use this cached record. Note that invalidation does not trigger any refetch unless specified inside useSubscribeToInvalidationState hook.

Imperative Refetch

Relay provides for fetchQuery and useQueryLoader for imperative usage. We can trigger imperative re-fetch on mutation completion.

Conclusion

If server can respond to mutation with the updated record, let Relay use server response to update its cache. When server response is insufficient, we can read & write pretty much any value inside Relay cache using updater function as long as we know how to locate the records of our interest.

--

--