React itself provides some useful methods for setting component states using setState() and adding a “local state” to a class.

With this option, you can call these methods for your components. setState() tells React that this component and its children (sometimes delayed and grouped into a single batch) should be re-rendered with the most updated state, often bases on user-triggered events. setState() will always lead to a re-render as long as an update is available ( shouldComponentUpdate() ). By adding a “local state” to a class, you can move data from the props themselves onto a state which can be updated.

Managing States with nothing but React itself is entirely possible, but can quickly become ineffective due to scaling complexity and performance issues (dependancies, redundant props, complex trees, etc). So, let’s move on to review React’s Context API- a feature built to solve exactly that.

React Context API (v16.3.0+): A promise of a better future?

The new React Context API, officially recommended from version React’s version 16.3.0, solves a major problem when setting component states: it lets you pass data through the component tree without having to manually pass props at every level of the tree even when not needed (prop drilling).

Using the context API you can share values between components without having to pass props. So far, the React team recommends using it to “share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language”. You might still need to add some code to compose providers and consumers (see this library), but no doubt this new “first-class” feature in React is a game changer.

A replacement to Redux? maybe. Here’s are a couple of short intros and tutorials to Context API and how to convert from Redux:

Hooks!

The new stable hooks introduced in React 16.8.0. let you create a custom hook to manage states inside functional components. Hooks states work pretty much like like class component states, while every instance of the component has its own state. This can be done with our without Context-API. You can use tools like Bit to easily share a reusable Hooks collection, and use them across your apps to speed and simplify the development of components.

Redux: It’s global but it works and there’s middleware!

We’ve finally arrived to the very (very) popular, sometimes dreaded, always to be talked about Redux. Above all, Redux favors predictability and control over your component states, making it a great choice for building consistent, cross-environment, testable applications with React.

“Redux is only a set of helpers to “mount” reducers to a single global store object. You can use as little, or as much of Redux, as you like.” — Dan Abramov

The Redux store, which is basically an object with some methods, works as a unified place to hold your application’s entire state tree. react-redux makes it simple to map your redux state onto React components (via connector functions, which are higher-order components on their own).

Redux-thunk, Redux-saga and Redux-observable are useful for working with asynchronous stuff which are less optimal when handled by Redux alone.

The result is a very practical way of making states predictable and immutable in React, with a time-travel option, state and action logging for debugging, simple to test React applications which work very well in production.

Although tempting, beware not to throw too much stuff into Redux. To some degree, this goes against the principle of self-contained components in React.

This can be particularly appealing for younger developers. Some claim that this approach might also -counter-intuitively- make it difficult to debug and control state updates at scale, and can cause trouble getting a grip on what’s going on and why it’s happening. While Redux is the de-facto solution for State management in React, you might not really need it.

Unstated: This is so elegant ✨