Context API Vs Redux
Overview
Managing the state is important for medium to large projects, in smaller projects, we can get away with the local state without using any external libraries.
Proper state management stops us from passing props to deeply nested components, which is called prop drilling. In some cases, we need a global state but not everything should be in a global state so proper management should be done.
To solve the problem of state management, Redux, and Context API are the most popular solutions. They aim to solve the same problem but tackle them using a different approach.
Introduction
To get into the discussion of context API vs redux we first have to clear some concepts of data flow in applications.
One of the functionalities of an application is to send data from one component to other. Developers use prop drilling to pass data between the disconnected components in React.
By default, there is no global state that the components can access, so if we have to pass data then we have to use props to pass the data between components at different levels. This results in a lot of repeated code and also a lot of bugs.
To solve the problem of prop drilling we create a global state that all the components can access, regardless of what level of nesting they are at.
What Is Redux?
Coming to our first contender of context vs API discussion, Redux.
Redux is an open-source library that behaves like a central store where all the data of the application is stored. Redux contains actions that are used to modify this central store. This store of redux is shared across the entire application and is updated predictably, thus it reduces the chances of many bugs that are related to state updates.
One thing to note here is, Redux is not only limited to React, it can be used with other frameworks also like Angular and Vue.
In Redux there are three main concepts:
- Actions
- Reducers
- Store
Let's understand these in detail
Actions
The only source of data for the store in Redux is actions. Actions are objects that are used to send data to the store. An action object has two properties:
- type
- payload
The type attribute tells what type of action is performed, this tells us what the action has done.
The payload is an object that contains the data that your reducer will use to update the state. This is the data that we want to pass around the components or store in the state.
This is how an action looks in redux
Explanation
Here we make a simple arrow function that takes the payload as an argument and returns a type and payload.
You can notice that in type we have used uppercase letters. This is a common naming convention that programmers follow to describe the type.
Example: ADD_DATA, ADD_USER
Reducers
Now that we know what needs to be done from the action, we need to write the code that will perform that task. This is where reducers come in.
A reducer is a pure function where the implementation of the action based on the action's type is present. The reducer takes in the current state which is the global state then performs the action and returns a new state.
Let's look at an example of a reducer
Explanation
We have created a function that accepts state and action as arguments. First, we extract type and payload from the action that is passed as an argument. Then we can write a switch or an if-else ladder to decide what to do based on the type of action.
Store
A popular way to describe the state is Single Source of Truth. This is true because storing all the data in a single place allows us to manage it easily and reduces the possibility of bugs.
So we can say that the state of the application is housed in the store. One Redux application can have only one store.
Creating a store is super simple
What Is Context API?
Now let's put some light on the other contender of context API vs redux discussion, the Context API.
Context API was introduced with React v16.3. React Context API solves a basic problem that we face in most of the React apps: How do we pass data from one component to another if they are not directly connected?
One solution to this problem is Prop Drilling which is a naive way and it introduces a lot of unnecessary code.
React Context API enables us to share data between components without using props. What React Context API does is, offers a means to transfer data along the component tree.
React Context API has three main things
- Context
- Provider
- Consumer
Let's see how we can create and use the Context API in React
First, we create a context by using the createContext hook
The job of the Provider component is to make the state available to all the child components. A value prop is passed to the Provider component where we pass our current value.
Now we will wrap the parent component with the <Provider/>
Now we can consume the value of context anywhere in the <AppProvider/> component with the help of the useContext hook.
Difference Between Context API and Redux
Let's look at the differences between Context API and Redux for the context API vs Redux discussion.
Context API | Redux |
---|---|
It comes built-in with React | It is an independent library and needs to be installed |
Only available for React | Can be used with other libraries like Angular and Vue |
Does not increase the bundle size | Increases bundle size |
Minimal setup is required | Initial setup takes time |
Learning context is easy | Redux has a learning curve |
Designed especially for static data that is not refreshed or updated often | It works well with both static and dynamic data |
Adding new contexts requires creation from scratch | After the initial setup, the extension is easy |
Due to highly nested Component Structure debugging becomes hard | Redux Dev tools are used to aid debugging |
UI and State logic reside in the same component | UI, and State logic are separate, thus it has better code separation |
Example
To better understand Redux vs React Context API we will go through two examples.
We will build a Theme Switcher and a Counter in both Redux and React Context API. This will help us to better understand both approaches.
The Redux Approach
Theme Switcher
First, we will create a store
Then create the actions
Finally, create the reducers to handle the actions and state updates
Now that our setup is done we can use this inside our application with the help of a Provider from react-redux.
Counter
First, let's create actions
Now the time for reducers
Let's make the store
No, we have to wrap our app with <Provider/>
We can use useSelector() and useDispatch() hooks to access the state anywhere in our code.
Context API Approach
Theme Switcher
First, we make a Theme Context.
Now we will create a Provider
Now we will wrap our app with this Provider
Counter
First, we make the context
We also have to make the reducer
Now we will provide the context
Now we will consume the context
Now we can write the implementation of increase and decrease functions
Conclusion
From this article we have learned:
- Managing state is important in web applications.
- Properly managing the state avoids a lot of unnecessary code and bugs.
- Developers have to do prop drilling if they have to pass data between components that are nested deeply.
- The solution is to use a global state that the components will access without caring about at what level they are.
- Redux is an open-source library that creates and manages a global shared state which is referred to as a single source of truth.
- Actions and reducers are used to manipulate this store.
- React Context API is a state management solution that is built-in with react.
- Context API eliminates the problem of prop drilling by creating a global context. The key components are Provider, Consumer, and Context.