Reputation: 6013
I'm learning how to use Apollo Client for React and how to manage local state using the cache. From the docs, it's as simple as writing to the cache using cache.writeData
and reading from it using a simple query. Their example is
const GET_VISIBILITY_FILTER = gql`
{
visibilityFilter @client
}
`;
I then wrap my JSX in a Query and can read the value fine (in my case loggedIn
)
return <Query query={GET_LOGGED_IN}>
{({loading, error, data}) => {
const {loggedIn} = data
I'm curious, though, why I don't need to write a resolver for this to work. Is it because with scalar values if a value exists at the root of an object, that is, here at the top level of the cache, Apollo/GraphQL automatically just grabs that value and sends it to you without a resolver?
What are the limits of this, that is, could you grab arrays at the root level without writing a resolver? Objects? I'm assuming not, as these don't seem to be scalars. But if the data is hard-coded, that is, doesn't require any DB lookup, the answer is still no?
Upvotes: 1
Views: 953
Reputation: 8418
In addition to a great (as usual) answer from Daniel, I would like to add a few words.
You can use (read/write) objects to cache and manipulate its properties directly.
Using resolvers and mutations for local data can help with readability, data access/change unification, overal manageability or future changes (move feature/settings to server).
More practical/advanced example of local state managament you can find in apollo-universal-starter-kit project.
Upvotes: 1
Reputation: 84677
From the docs:
[The @client directive] tells Apollo Client to fetch the field data locally (either from the cache or using a local resolver), instead of sending it to our GraphQL server.
If the directive is present on a field, Apollo will attempt to resolve the field using the provided resolver, or fall back to fetching directly from the cache if one doesn't exist. You can initialize your cache with pretty much any sort of data at the root level (taking care to include __typename
fields for objects) and you should be able to fetch it without having to also provide a resolver
for it. On the other hand, providing a resolver can provide you with more granular control over what's actually fetched from the cache -- i.e. you could initialize the cache with an array of items, but use a resolver to provide a way to filter or sort them.
There's an import nuance here: Fetching without a resolver only works when there's data in the cache to fetch. That's why it's important to provide initial state for these fields when building your client. If you have a more deeply nested @client
field (for example, maybe you're including additional information alongside data fetched from the server), you also technically don't have to write a resolver. But we typically do write them because there is no existing data in the cache for those nested fields.
Upvotes: 4