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?
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.
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.
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.
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.
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.
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:
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.
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 connect
ed 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With