Redux or Context - Is there a clear choice?

When we first start studying React, the idea of having stateful components that can store and manipulate information locally opens up many possibilities that allow us to write more efficient Front-End applications. It becomes possible to use that stored information, in turn, to render and update these components in real time on the browser.

However, when these applications begin to take more complex forms, with components forming long chains and trees with ever-growing branches, managing state that communicates with multiple components, it soon becomes quite challenging to maintain, leading to the dreaded practice of "prop-drilling" or "prop-hell" if one is not careful.

To help us with that, there are some tools that allow us to store all that information globally, and make it accessible from anywhere in the application. Two of the most used ones are Redux, which is, according to its own documentation, a "predictable state container for JS apps", and Context API, which is a native React solution that was definitely implemented in version 16.3.

We're soon faced, as developers, with a clear bifurcation. But which one to choose?

Redux

The Redux library, besides allowing a consistent and relatively simple control of global state through its reducers, actions and dispatches, also makes debugging problems related to that state much easier to debug, since its toolset includes a chrome extension that enables logging all state changing events in chronological order, as well as reverting the global state to a previous moment in time.

But not everything about Redux is great. First of all, it usually requires quite a considerable amount of boilerplate code to setup: you have to create files to house the store, the reducers that manipulate the store, the actions that will be dispatched to the reducers, functions that will generate new instances of the action objects, and in the end it might be more trouble than it's worth to try and use Redux in smaller applications.

Besides that, Redux as a tool is not very beginner-friendly and all of it can take a while to begin making sense, since there are many small pieces to worry about. This steep learning curve may discourage some people from beginning to use it at all.

And when Redux isn't worth it, we have the Context API.

Context API

A first contact with Context may already garner points for its usage, since it's much simpler to set up and doesn't require you to install new libraries besides React itself (as long as its version is equal or higher than 16.3), being a native React API. Like Redux, it also allows us to create and manage a global state for our app, supplanting the need to pass prop information through the component hierarchy.

The way you use Context is also much simpler than with Redux, at least in its raw implementation. All you need to do is to create a context object using the ‘createContext()’ function and use this object to create a Provider component that will be placed in the base of the component tree, wrapping all components that may need to access this state.

By using the Context API, we have a simpler, more streamlined process that is much easier to work with than the process of creating a Redux store management in our app. But does this single fact turn Redux into an obsolete tool? Not at all!

Chhosing the right tool

In the first place, Redux should always be considered, even in smaller applications, if you aim to separate the concepts of state (Redux) and interface (React) within the code. The act of separating concerns in computer science is generally regarded as a good practice that can make code cleaner and easier to maintain.

Of course, you can also separate the components and state management hooks as well with Context, but it does remain bound to the React side of the app, since it’s essentially a part of it. In Redux this separation is more pronounced - so much so that you can use it in other applications that are not built with React.

In addition, once you have the knowledge of how the Redux state works and of how to interact with it, it is possible to cut most of the boilerplate using the Redux Toolkit, which is an official Redux library that streamlines its boilerplate configuration and makes it easy to create a complete Redux system (with well-known tools like Redux Thunk and Reselect), with functions that do pretty much all the work of setting up the storage.

The ‘createSlice()’ function, for instance, automates the creation of reducers, actions and action creators, which can be defined with a much simpler syntax in a single object passed as a parameter!

The ‘configureStore()’ function, on the other hand, makes creating the store much simpler, as it already combines your reducers, adds whatever middleware you want (and the Redux Thunk is already added by default) and even configures the Redux developer tool, everything without you having to worry about unnecessarily complex or lengthy boilerplate code.

On the other hand, Context remains as the simplest tool to use, and when the global state is not complex it really outshines Redux, even with its simplifying toolset. It can also scale well if the system design separates the concerns well enough and uses things like custom hooks to make it easy to maintain and control the global state, even without the powerful debugging features of Redux.

Ultimately, when picking between Redux and Context, there is no absolute answer. The important thing is to know both and make informed architectural decisions that will allow you to say goodbye to prop drilling by having a global state in a separate section of your code that is clean, scalable and easy to maintain.

To view or add a comment, sign in

More articles by Silvio Dayube Carigé

Insights from the community

Others also viewed

Explore topics