SyntaxStudy
Sign Up
GraphQL Apollo Client Cache Policies and Local State
GraphQL Beginner 1 min read

Apollo Client Cache Policies and Local State

The InMemoryCache normalizes data by splitting query results into individual objects identified by their type and id. Field policies let you customize how the cache stores and reads individual fields—essential for implementing pagination with keyArgs and read/merge functions. Apollo Client also manages local-only state through reactive variables and local-only fields (marked with @client directive). This replaces the need for a separate state management library for UI state, keeping all data access—remote and local—through the same GraphQL query interface.
Example
import { InMemoryCache, makeVar, gql, useReactiveVar } from '@apollo/client';

// ----- Reactive variable for local state -----
export const isLoggedInVar = makeVar(false);
export const cartItemsVar  = makeVar([]);

// ----- Cache with field policies -----
const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        // Cursor-based pagination merge policy
        posts: {
          keyArgs: ['filter'],     // separate cache entries per filter
          merge(existing = { edges: [] }, incoming) {
            return { ...incoming, edges: [...existing.edges, ...incoming.edges] };
          },
        },
        // Local-only field backed by reactive variable
        isLoggedIn: {
          read: () => isLoggedInVar(),
        },
      },
    },
    Post: {
      fields: {
        // Computed local field
        isLiked: {
          read: (existing = false) => existing,
        },
      },
    },
  },
});

// ----- Using reactive var in component -----
function LoginStatus() {
  const isLoggedIn = useReactiveVar(isLoggedInVar);
  return <span>{isLoggedIn ? 'Logged in' : 'Guest'}</span>;
}

// ----- @client directive reads from cache/reactive var -----
const GET_UI_STATE = gql`
  query GetUIState {
    isLoggedIn @client
  }
`;