Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get updated data from apollo cache

Does Apollo client have some sort of thing like mapStateToProps (Redux)?

let's say I have a component, after query I know there's data in the cache so I do something like:

    class Container extends React.Component {
      ...
      ...
      render() {
        const notes = this.props.client.readFragment(NOTES_FRAGMENT)
        // notes has everything I need
        return (<Child notes={notes} />);
      }

    }
    export default WithApollo(Container);

However when I have a sibling component which calls mutation and do update, the <Child /> component's props never get updates.

class AnotherContainer extends React.Component {
   render() {
     return(
       <Mutation
          mutation={UPDATE_NOTE}
          update={(cache, {data: {updateNote}}) =? {
            const list = cache.readFragment({
              fragment: NOTES_FRAGMENT
            })
            // manipulate list
            cache.writeFragment({fragment:NOTES_FRAGMENT, data })
          }
        }
     )
   }
}

so my question is, how do I update the <Child /> component's props whenever I do writeFragment? is there anything like mapStateToProps thing to "connect" the notes props to the cache, so whenever it updates, will trigger the React lifecycle?

like image 961
Yichaoz Avatar asked May 15 '18 03:05

Yichaoz


People also ask

How do you update the Apollo cache after a mutation?

If a mutation updates a single existing entity, Apollo Client can automatically update that entity's value in its cache when the mutation returns. To do so, the mutation must return the id of the modified entity, along with the values of the fields that were modified.

How does the Apollo cache work?

Apollo Client stores the results of your GraphQL queries in a local, normalized, in-memory cache. This enables Apollo Client to respond almost immediately to queries for already-cached data, without even sending a network request. The Apollo Client cache is highly configurable.

Is Apollo cache persistent?

By default, the contents of your cache are immediately restored asynchronously, and they're persisted on every write to the cache with a short configurable debounce interval.

How to update Apollo cache with new data from mutation result?

The first argument supplied will be the Apollo cache, and the second will be the mutation result object. The cache is capable of reading the result of any existing query in the store via readQuery and then we can update the cache with new data from out mutation result using writeQuery.

How do I manage cached data in Apollo client?

Apollo Client supports multiple strategies for interacting with cached data: Use standard GraphQL queries for managing both remote and local data. Access the fields of any cached object without composing an entire query to reach that object. Manipulate cached data without using GraphQL at all.

Where is my data stored in Apollo?

That data is stored in Apollo’s cache, based on the name of the query you execute, as well as any variables you pass to it, like this:

What is the difference between update and refetchqueries in Apollo?

While refetchQueries would be the third option, update is the Apollo’s recommended way of updating the cache after a query. It is explained in full here.


Video Answer


1 Answers

react-apollo provides three ways you can listen for changes in the cache: 1) the Query component, 2) the graphql HOC, and 3) calling watchQuery directly using the client. In all three cases, you provide some query and any appropriate options, and you get a way to initially fetch that query as well as listen to updates to it.

The key here is that queries, and not fragments are the intended vehicles for reading the cache. The readFragment method is only meant as a convenient way to read the cache a single time (usually in the context of changing the cache after a mutation) and does not provide any sort of reactivity.

So, bottom line, wrap your components in either the Query component or the graphql HOC and you will have access to props that reflect the query results in the cache and that will update when the cache updates (the same way connected components do).

At this point a couple of things might be going through your head:

"But I don't need to make another server request!" No worries -- by default, Apollo will only request the same query once, and will use the cache for all subsequent calls. You can modify this behavior by setting the appropriate fetch policy for your query. This includes a cache-only policy that will only pull data from cache (although the default cache-first policy is sufficient for most use cases).

"But I don't have a query to work with!" If you're writing to the cache as a means of persisting some arbitrary client-side state, then you should be using apollo-link-state to do so.

"But I don't need the entire query result, just a part of it!" The graphql HOC provides a props function you can pass in to the configuration that will let you transform your query data into whatever shape you want to work with. The same functionality isn't really needed when using the render props pattern with the Query component -- you can just manipulate the render props directly. In either case, it may be a good idea to write some reducers that you can reuse throughout your project that just take the returned data and transform it into the shape you need. The last big project I worked on did just that client side and it kept things much more manageable.

like image 174
Daniel Rearden Avatar answered Oct 10 '22 13:10

Daniel Rearden