Why we still need to use state management libraries in React?

Why using just React’s state mechanism is a bad idea

MustSeeMelons
Feb 3 · 3 min read
Photo by Guillaume Bolduc on Unsplash

Introduction

Now that we have hooks and the Context API , it may seem appealing to forgo a state management library when starting a new project in React — should we give in to the temptation? Let’s find out by looking at a simple shopping cart example, starting at the bottom of the tree — item list view.

At the bottom

A context consumer component would look something like this, granted, this is quite a simple example, but it illustrates the main points of interest well. It simply renders a list of items, which can be added or removed from the cart.

 SimpleItemList = ()  {
// Using the hook to gain access to the context
context = useContext(GlobalContext);

return (
<div>
{context.items.map((item, index) {
return (
<Item
key={index}
item={item}
onAdd={() {
context.addToCart(item);
}}
onRemove={() {
context.removeFromCart(item);
}}
/>
);
})}
</div>
);
};

At first, it seems to be good as this does not require passing in any props, just directly tapping into everything we need from the context.

This has a few downsides though:

  • component re-use is harmed because it is directly coupled to a context
  • it is much harder to reason at first glance what variables this component needs as there are no props

We could pass in the context as a prop for the component to make it more re-usable.

 context = useContext(props.context);

If we were to use Typescript we could specify that the props of the component extend some kind of base interface describing what we expect the context to look like, but I can’t recommend such doing such a thing as it just seems like a hack, the option exists if the circumstances are bad enough.

At the top

We define our applications state, together with the functions necessary to work with it and use the Context API to expose it to our other components.

To use the Context API, we need to wrap our application with the context provider component, so that the children that need it can access our context.

 SimpleStateApp() {
addToCart = item {
setState(prevState {
copy = { ...prevState };
if (copy.cart[item.id]) {
copy.cart[item.id].count++;
} else {
copy.cart[item.id] = { ...item, count: 1 };
}
return {
...copy
};
});
};
removeFromCart = item {
setState(prevState {
copy = { ...prevState };
if (copy.cart[item.id].count === 1) {
delete copy.cart[item.id];
} else {
copy.cart[item.id].count--;
}
return {
...copy
};
});
};
[state, setState] = useState({
addToCart: addToCart,
removeFromCart: removeFromCart,
items: [...ITEMS_ARRAY],
cart: {}
});
return (
<GlobalContext.Provider value={state}>
<div className="App">
<header className="App-header">
<div>This is the Simple barn</div>
</header>
<SimpleItemList />
<SimpleCart />
</div>
</GlobalContext.Provider>
);
}

It works like a charm! Though it exposes a few things:

  • This is still a local state of a single component, tightly coupled to it
  • Increasing the complexity of the business logic will increase the complexity of the root component

Conclusion

I made it look worse than it is as there are ways of avoiding putting everything directly into the root component, the state functions could easily be moved into separate files and just imported at the root, but I think it would be better to use a proper state management library to decouple the global state from any single component, keeping the components as simple as possible, having the state they only need to function.

You can check out multiple ways of managing state for the same app in this repo.

JavaScript in Plain English

Learn the web's most important programming language.

MustSeeMelons

Written by

JavaScript in Plain English

Learn the web's most important programming language.

More From Medium

More from JavaScript in Plain English

More from JavaScript in Plain English

How to Secure Your API With JSON Web Tokens

More from JavaScript in Plain English

More from JavaScript in Plain English

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade