Reactive State Management with Apollo Client React

mohit thakur
Apr 14 · 3 min read

Who is the audience?

Anyone struggling with React applications component hell and prop drilling will find this article helpful.

What you should know beforehand?

Should be familiar with React and Redux or Ngrx if you come from an angular background.

What is the Problem?

There are lots of problems with state management with Apollo, worked on both angular and React it feels like just caching API doesn't mean you have done state management. You should be able to consume data easily with any state management library. Apollo is very poor at client-side state management.

What is the client-side state?

The data is not present on the server but is required only in the front end to take actions on the view.

When you try to set a global modal and you want to show and hide this on some condition, you don’t keep this flag on server but is managed in client side.

Apollo Client Reactive Var to Rescue?

If you have worked with Apollo it says everything is magic, believe me, it is not. If you come from Redux background, you can already understand what I mean.

Enough of lecturing lets get our hands dirty

Lets try make a currency search component, where we can enter to filter out currency by their name initials.

Folder Structure

Lets see example container

import React, { Fragment, useEffect } from "react";
import { Col, Container, Row } from "react-bootstrap";
import { exampleState } from "../localstate/example";
import { SearchExample } from "./search";
import { useApolloClient, useQuery, useReactiveVar } from "@apollo/client";
import { GET_RATES, GET_RATES_PLUS_CLIENT } from "./queries/queries";
import { Item } from "./item";
export function ExampleContainer(props) {
const state = useReactiveVar(exampleState);
const client = useApolloClient();const { loading, error, data } = useQuery(GET_RATES);useEffect(() => {
console.log(state, " state changed");
client.query({ query: GET_RATES_PLUS_CLIENT }).then((data) => {
console.log(data, " got this data suing query");
});
}, [state.searchString]);
if (loading) return <p> loading</p>;
if (error) return <p> error</p>;
return (
<Fragment>
<Container>
<Row>
<Col xs={12}>
{state.searchString}
<SearchExample />
</Col>
</Row>
<Row>
{data.rates
.filter((f) =>
f.currency.includes(state.searchString.toUpperCase())
)
.map((item) => {
return <Item currency={item.currency} />;
})}
</Row>
</Container>
</Fragment>
);
}

if you take a closer look at above component you will see less props being passed around , what we are using instead is a Reactive Var from Apollo Client to share the client side state among component.

So no call back hell anymore.

Lets take a look at client side Reactive file

// shape of your local state
export interface ExampleState {
searchString: string;
items: Number[];
orgid: Number;
SelectAll: Boolean;
}
const initialState = {
searchString: "",
items: [],
orgid: null,
SelectAll: false
};
export const exampleState = makeVar<ExampleState>(initialState);

I know what you are thinking it looks like a behavior subject and it is quite similar, it is based on Zen observable , little brother of Rxjs.

How to consume Reactive Var, Apollo gives you useReactiveVar Hook

Now any component that has this state can listen to changes in state easily with effects.

Our container component can listen to changes in search string and filter the list of currencies

client.query({ query: GET_RATES_PLUS_CLIENT }).then((data) => {
console.log(data, " got this data suing query");
});
}, [state.searchString]);

Any change to state.searchString will trigger a new search .

That’s it no callbacks , happy coding. Can check out working example at

here

Leave a clap if you enjoyed this example :)

Geek Culture

Proud to geek out. Follow to join our +500K monthly readers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store