Since the launch of Redux in 2015, it has been the preferred solution for state management. Because of that by the time “you should learn Redux” has become a universal truth. Many people start to use Redux without knowing why actually we need Redux. Because there are situations, Redux is not the best option we have.
Before start using Redux, it is important to understand how to use it. Especially because there is another solution, which is a supplementary solution Reacts Context API!
Before we start talking about React, we need to have an understanding of two more things.
- what is state management means?
- why we need it?
what is state management means?
The state is encapsulated data where you store assets that are persistent between component renderings. If a user changes state by interacting with our application, the user interface may look completely different after that, because it is represented by this new state rather than the old state. State management is a repository of the current state of the application and its data. This is a common part of all views. For example, let us say for user data; full name, age, profile picture, hobbies are stored in state.
why we need it?
In typical react, the way we are dealing with the data between disconnected components is through passing props. Because there we do not have a global state that components can access. Let us assume we want to pass data from a top-level component to a third level component, so we will have to pass the data as props to each level of the tree until finally, we get it to our desired component. This results in writing more extra code as well.
To solve this issue, we need a global state that helps us to easily access the data, even though our component structure is deeply nested.
What is Redux?
however, as a disadvantage of prop passing, we must write a considerable number of extra codes. But with the Redux this problem becomes more severe because Redux requires mainly three building parts to function, they are actions, reducers, and store. So, all the additional code blocks it requires for setting up a global state introduced us even more complexity.
Here is a simple example of how we are using redux in a notes app.
Here we use a manually initiated notes list. And the provider received the configured store.
These are pure functions that implement the action behavior. They take the current state of the application, perform an action, and then return a new state.
These are objects that are used to send data to the Redux store.
This is the component connected with Redux.
mapStateToProps — this determines which data is injected into the notes display component.
mapDispatchToProps — determines which actions are injected into the component and which can manipulate the data from this state.
What is the React Context API?
The React Context API introduced with React 16.3. React Context API is a built function that enables sharing of data with nested components. One major difference is comparing to Redux it is built into React and does not require any additional library installations. The React Context API is the Reacts way of managing state in multiple components that are not linked directly.
Here’s how Context API explained in react documentation.
“Context provides a way to pass data through the component tree without having to pass props down manually at every level.”
Here we are using React Hooks, bases for functions that simplify data positioning within components. The component blocks we need are Context Object, Context Provider, and Context Consumer.
Before we dive into Context API implementation. We need a basic understanding of how React Hooks works.
What are React Hooks?
Hooks are a new addition introduced in React 16.8. They let us use state and other React features without writing a class component. This means React Hooks provide an alternative way to writing class-based components by allowing us to easily handle state management from functional components.
Let’s create a React Context! And try to get a basic idea about how to implement it. Then we can change the previous notes app state management using context API.
To create a context, we need to use the createContext method of React. By default, it accepts a parameter.
The createContext method will return two objects which are consumer and provider.
The provider component which we get from the createContext method is the one which make state available to all the other child components. This component receives a prop called value which we pass our current value.
The next one, the consumer component is the used consume the state or the data in the state. That helps to use the global data without passing props.
Here there are two main scenarios according to component type,
- If we need to access the global state data in a class component, then we do it as below.
2. If the desired component we need to access the global data is a functional component, we needed to wrap our content in a consumer component and then pass a function as a child just so we could access and consume the state.
Anyway, this introduces unnecessary component nesting to our code.
But with React Hooks , in functional components, we can the access context using the useContext hook.
The useReducer Hook
The useReducer Hook receives two values as its argument a reducer function and an initial state) then returns to a new state.
When we call the dispatch method, the useReducer hook will perform an action based on the type that our method receives in its action argument.
Here is how the context API used in the notes app we did previously.
This is how context implement using createContext method in react. And add the value prop to the provider component.
To access the created context from the app we need to wrap the app component using the provider component.
To access the global state from the notes.js here we used the useContext React Hook.
Now let’s see how to use useReducer hook with Context API in the notes app!
This is how we can access the state globally.
Implementation of the other components will be the same as the previous.
Will React Context API replace Redux?
Most probably it will not because currently many projects implementing using Redux. As I think both solutions Context API and redux will exists. Context API is a way for sharing the state through the nested component tree and it's not a direct solution state management. If we use Redux just to avoid transferring props in the nested component tree, then we can use Context API instead of that. But in Context, there are no some other features we have with Redux such as Redux developer tools, middleware for adding centralized logic, state update tracking, and many other Redux-specific features.
Should I use Context API or Redux?
This is the final question all of us have now. First, let’s take the Context, it can implement easily and does not need to install third party libraries since it comes with React itself. Most of the time good for static state data because it does not update frequently like Redux. Applications can add multiple contexts and separate the logics. Finally, we get a smaller package and that helps better project maintenance. But the main drawbacks of Context API are that it is not designed to use with refreshing data.
On the other hand, when thinking about Redux it is designed to use with frequently changing data and easy to test the codebase. Redux has access to middleware for async actions when we use redux-thunk or redux-saga and expand the store with this functionality. It helps to maintain a good code structure as well. Unnecessary re-renders and refreshes are eliminated by Redux when changing the store object. But there are several drawbacks to Redux as well. Since It is not built-in React, which increases the size of the package inconsiderable amount. We need to externally install the Redux library. Even if used with Redux Toolkit, it can be confusing for beginners. And obviously It requires more configuration than Context API, and the learning curve is considerably high.
So, what should you choose? Context API or Redux?
The answer is it depends on the project or application we are going to implement. Because we do not need to find out that it increases in size later and rewrite it from Context to Redux. And we need to consider how the data changing, refreshing and how often that happens. Simply we need a clear idea about what is our project and its scope. If the application is a large one better to use Redux for the global state management because it is a very powerful state management library. If the project is a small one, then we can go with our next option Context API.