Apollo 8: Reactive Variables
easy⏱ 5 mincourseapollo
makeVar and useReactiveVar
Reactive variables are created with makeVar(initialValue). They live outside the cache but can be read from within it. Use useReactiveVar(myVar) in components to subscribe to changes — the component re-renders whenever the variable updates. Update the value by calling the variable as a function: myVar([...myVar(), newItem]). No providers, no actions, no reducers.
import { makeVar, useReactiveVar } from '@apollo/client';
// Create the reactive variable
const favoritesVar = makeVar([]);
// Read in a component
function FavCount() {
const favorites = useReactiveVar(favoritesVar);
return <span>{favorites.length} favorites</span>;
}
// Update from anywhere
favoritesVar([...favoritesVar(), 'item-1']);
Build local favorites with reactive vars
Create a favoritesVar with makeVar([]). Build an ItemCard component that shows a product and a heart/star toggle. When clicked, add or remove the item ID from favoritesVar. Build a FavoriteCount badge that uses useReactiveVar(favoritesVar) to display the count. No server queries needed — this is pure local state.
@client directive for local fields
You can read reactive variables inside GraphQL queries using the @client directive and a read function in type policies. Define a local field: Query.fields.favorites = { read() { return favoritesVar(); } }. Then query it: gql'query { favorites @client }'. This unifies local and remote data into one query, which is powerful for components that need both.
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
favorites: {
read() {
return favoritesVar();
},
},
},
},
},
});
// Query local state alongside remote data
const GET_DATA = gql`
query GetData {
products { id name }
favorites @client
}
`;
Reactive vars vs Context
Reactive variables solve the same problem as React Context but with key advantages: no provider nesting, no re-render of the entire tree (only subscribers re-render), accessible from outside React (in utility functions, link chains), and queryable alongside remote data via @client. Use Context for theme/auth, reactive vars for fine-grained local state.