Skip to content

State Management with Apollo Client (Reactive Variables)

Introduction

State management is one of the most common problems for frontend developers and mobile developers. Most of the new frameworks come with a built-in state management system like Vuex and Pinia for Vue, and Svelte Store for Svelte. But because of the lack of state management in the ecosystem of React (Also because React is a library, not a framework), developers have to use variance state management systems like Redux and XState. But the problem is that the state management system is not easy to use, and they usually add more code to the final build bundle. Most of projects nowadays use GraphQL, and the most popular tool for GraphQL is Apollo. But did you know that you can use Apollo itself as a state management library for your project instead of adding more code to the final build bundle? That's what we are going to do in this tutorial.

What is GraphQL?

GraphQL is a query language for APIs, and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

Apollo Client

Apollo Client is a client for the Apollo GraphQL server. It is a library that allows you to easily integrate GraphQL queries and mutations into your React application. It is a state management system for your React application, and it has a lot of state management features behind the senses that you can use to manage your application state as an alternative to Redux and XState.

Reactive Variables

Reactive variables are new features that came with Apollo Client 3. From the documentation:

"Reactive variables are a useful mechanism for representing local state outside of the Apollo Client cache."

And their power comes from the fact that they are separated from the cache and you can use them to store any kind of data type or structure.

Create your first Reactive variable in Apollo

Create a reactive variable with the makeVar method, like so:

import { makeVar } from '@apollo/client';

const isDarkModeVar = makeVar(false);

and then you can use isDarkModeVar() like so:

console.log(isDarkModeVar());
// Output: false

isDarkModeVar(true);

console.log(isDarkModeVar());
// Output: true

Also you can use useReactiveVar hook to get the value of the variable inside React components:

import { useReactiveVar } from '@apollo/client';
import { isDarkModeVar } from './variables/isDarkMode.js';

export function HomePage() {
  const isDarkMode = useReactiveVar(isDarkModeVar);

  return (
    <div>
      <h1>
        {isDarkMode ? 'Dark Mode' : 'Light Mode'}
      </h1>
    </div>
  );
}

Reactive components in the Queries

For more advanced use, you can use the reactive variables in the Apollo client in the GraphQL queries as well, and update it automatically, for example:

Let’s say you want to fetch a list of products, and want to save them.

export const GET_PRODUCT_ITEMS = gql`
  query GetProductItems {
    productItems @client
  }
`;

And now we should initialize a reactive variable productItemsVar for example:

import { makeVar } from '@apollo/client';

export const productItemsVar = makeVar([]);

In cache.js let’s do this:

import { InMemoryCache } from '@apollo/client';
import { productItemsVar } from './variables/productItemsVar.js';

export const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        productItems: {
          read() {
            return productItemsVar();
          }
        }
      }
    }
  }
});

And now we can use productItemsVar instead of querying it from the APIs each time.

Wrapping Up

Apollo Reactive variables are great features in Apollo 3+, and you can save a lot of work by using them instead of Redux and XState, especially if you are already using Apollo client and GraphQL in your project. Also, its power comes from its simplicity. Just create a global state variable by one line of code.