When to Use Context API vs Redux in Your Next React Project

Understand the differences between Context API and Redux before deciding between the two for state management in your React project.

Miraz Hossain
Bits and Pieces

--

If someone would ask me, what’s the most important piece of any website? My answer will always be the same. It’s the state management. After all, it’s the state that is deciding what users will see.

Effective state management is a critical aspect of building robust web applications. In React, the two most popular options for managing state at a global level are Context API and Redux.

When it comes to selecting a global state management solution for React, developers have plenty of options to consider. For a long time, Redux has been a popular choice among developers. However, with the introduction of Context API, developers started to quickly adopt it. In some cases, they even replace Redux with Context. All That Happening an important question arise, which one should I use?

When deciding between using Context API or Redux

If you’re using Redux just to avoid passing props, you can switch to Context API instead. Context API is perfect for sharing small bits of information between components. On the other hand, Redux is more powerful and comes with helpful features that Context API doesn’t have. It’s great for managing big chunks of data and handling requests to APIs.

The Difference Between Context API and Redux

The difference between Context API and Redux lies in how they handle state changes. Redux takes a centralized approach, where state changes are managed in a central store. On the other hand, Context API deals with state changes on a components level, as they happen within each component.

To better understand the distinction between these two libraries, let’s take a closer look at each one individually.

Context API

Context provides a way to pass data through the component tree without having to pass props down manually at every level. (source: React)

Context API is an exciting addition to the world of React. It offers a convenient way to share data across multiple components without the need to manually pass props at each level. This feature is particularly helpful when you have data that needs to be accessed globally within a tree of React Components. such as theme preferences or preferred language.

One of the main benefits of Context API is its ability to simplify state management in your application. By using Context, you can reduce the complexity of passing data between components and eliminate the need for additional actions or props. This can make your code more concise and easier to maintain. It’s like having a handy tool that streamlines the sharing of data among your components.

Context API has two core concepts:

  • Providers
  • Consumers

Providers is to define and keep track of specific pieces of state. This state can then be accessed by all the child components nested inside the Provider. These child components, known as Consumers, are responsible for accessing or modifying the state provided by the Context Provider.

Overall, Context API offers an efficient way to manage shared data within your React Application, making it a valuable alternative to passing props manually or using other state management libraries like Redux.

Redux

A Predictable State Container for JS Apps (Source: Redux)

Redux is a powerful JavaScript library that provides a centralized approach to managing data flow in your application. It’s designed to help you build consistent, testable, and versatile applications that can run in different environments. Redux offers some fantastic capabilities like undo/redo functionality, state persistence, and more.

With Redux, the entire state of your application is stored in a single place, making it easily accessible to any component without the need to pass props around. It operates based on three core concepts:

  • Actions
  • Reducers
  • Store

Actions represent events that send data to the Redux store. They can be triggered by user interactions or called directly by your application. Each action has a unique type and a payload associated with it. For example, an action for Adding Todo might look like this:

const addTodo = text => {
return {
type: 'todos/todoAdded',
payload: text
}
}

Redux is a pattern and library for managing and updating application state, using events called “actions” (source: Redux)

When an action is dispatched, it triggers the corresponding reducer function. Reducers take the current state and, based on the received action, return a new state that reflects the changes.

All of this happens within the store. The store is responsible for holding the application state. In Redux, it’s recommended to have only one store for your entire application.

Now that we have an understanding of both Redux and Context, let’s explore the different use cases and applications where each of them shines.

Use Cases of Context API

Note: You can check out the official document they recommended some use cases Link — Context_API

Context API is a powerful feature that comes bundled with React, providing a straightforward way to share data across components without the need for manual prop passing. It’s an excellent choice for managing lightweight, global data that remains relatively simple throughout the application.

Let’s look at an example of using Context API to manage the theme of a React application:

import React, {useContext, useState} from "react";

// Setting default theme values
const ThemeContext = React.createContext({
theme: "light",
setTheme: () => {},
});

const App = () => {
const [theme, setTheme] = useState("light");

return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<Hello />
</ThemeContext.Provider>
);
};

const Hello = () => {
const { theme } = useContext(ThemeContext);

return (
<h1 style={{ color: theme === "light" ? "black" : "white" }}>Hello</h1>
);
};

In this example, we create a ThemeContext using React.createContext() and set the initial theme value to light along with the setTheme function. The App component wraps the Hello component with the ThemeContext.Provider making the theme and setTheme values accessible to all nested components. The Hello component consumes the theme value using useContext and applies the appropriate color based on the selected theme.

Use Cases of Redux

Redux is commonly used in situations where:

  1. The application has a large amount of state that needs to be accessed by many components.
  2. The application state is updated frequently.
  3. The logic to update the application state is complex.

To better understand the ideal use case for Redux, let’s implement a piece of state that tracks the list of application users.

In the userReducer.js file, we start with an initial state of an empty array:

const initialState = [];

const userReducer = (state = initialState, action) => {
switch (action.type) {
case "SET_USERS":
return action.payload;

case "ADD_USER":
return [...state, action.payload];

case "EDIT_USER":
const newState = [...state];
const index = newState.findIndex((item) => item.id === action.payload.id);
newState[index] = action.payload;
return newState;

case "DELETE_USER":
return state.filter((user) => user.id !== action.payload.id);

default:
return state;
}
};

💡 By encapsulating your state update logic in userReducer, you’ll be able to handle complex state updates in a centralized and maintainable way. Now, if you wanted to reuse this complex state management logic in other projects, you could do so with an open-source toolchain like Bit. Learn more here.

To initialize Redux, we need to wrap the entire app component inside the Redux Provider and initialize the store.

In the App.jsx file:

import { Provider } from 'react-redux';
import { createStore } from 'redux';
import userReducer from './reducers/userReducer';

// create an instance of the store
const store = createStore({
users: userReducer,
});

const App = () => {
// set the store instance
return <Provider store={store}><Users /></Provider>;
};

export default App;

Lastly, to access the state, we can connect the component to the state using useSelector hooks provided by react-redux

import { useSelector } from 'react-redux';

const Users = () => {
const users = useSelector((state) => state.users);

return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};

export default Users;

Other State Management Tools

In this article, we’re going to discuss some other state management tools that you might find interesting. It’s important to note that we’re not trying to persuade you to use these tools or claiming they are superior to Redux or Context API. We simply want to spread awareness and give you more options to consider. So, let’s dive in and explore these tools! 🕺🏻

React-Query

One of the tools worth mentioning is React Query. It was specifically designed to handle state management related to data fetching. With React Query, you get a bunch of helpful utilities that make data fetching a breeze. If you want to learn more about React Query, you can check out their documentation -> React-Query

Recoil

Another interesting state management tool is Recoil, which is developed by Facebook. Although it’s relatively new, Recoil is actively being developed and improved. In Recoil, each piece of state is called an “atom,” and you can combine these atoms with selectors to create unique data structures tailored to your application. If Recoil piques your interest, you can find more information -> Recoil

MobX

Now, let’s talk about MobX. Unlike Redux and Context API, MobX follows a class-based approach. Its core concept revolves around making state management “observable.” By leveraging MobX, you can easily observe and react to changes in your application’s state. If you want to delve deeper into MobX, you can read more about it -> MobX

Concluding Thoughts

State management is an essential aspect of web applications, and it’s crucial to choose the right approach for managing the global state in your React application. The commonly debated question often revolves around when to use Context API versus Redux. Understanding how both Context API and Redux work is important, and selecting the appropriate tool for your use case is equally vital.

Throughout this article, we’ve provided basic examples of both Context API and Redux, along with their ideal use cases. Ultimately, we’ve addressed the question of when to use Context API versus Redux. Armed with this knowledge, you can confidently make the decision of when to utilize Context API or Redux. 👍

Build React apps with reusable components, just like Lego

Bit’s open-source tool help 250,000+ devs to build apps with components.

Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.

Learn more

Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:

Micro-Frontends

Design System

Code-Sharing and reuse

Monorepo

--

--