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:
User record has an
id field and an
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:
- Access it directly by its ID.
- Access the user which is linked to the
Postrecord of our interest, then follow the link.
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.
- Fetch the updated record from server.
- Use Relay
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
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
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
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
RecordProxyof 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.
Alternatives to Cache Update
Maybe your issue can be resolved without updating Relay cache. Consider these alternatives before writing your
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
Relay provides for
useQueryLoader for imperative usage. We can trigger imperative re-fetch on mutation completion.
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.