React’s Context API and How it can replace REDUX

vishal.chandna   |  1st November, 2018

React is a great library used to build the user interfaces but when it is combined with tools such as Redux, Reselect, Router and more, it really takes the lead in terms of performance and reusability. Well, these may sound like some really cool stuff but these are really complex and expensive especially Redux.

What is Redux?

Redux is primarily a tool used to manage the business logic of the front-end. It can be integrated with any JS framework but with React, it is just seamless. Its best part is it helps to create the code completely reusable, very easy to maintain and completely separated from the UI. To learn more about the Redux - https://redux.js.org/

Why and When to Use Redux?

ReactJS is a great tool to create UIs but it also needs some data store, date inputs and data manipulations. Keeping the data binded inside the components itself works well for small applications but for bigger applications, it can become really messy and can cause regression issues. So Redux is a cure for mid-scale to big-scale applications which act as a central store for components data and provides a way that helps in data manipulations easily.

Pros Of Redux

  1. Business logic is completely separated from the UI
  2. The code is easy to maintain and very reusable.
  3. Heaven for mid to large scale applications.
  4. Have its own debuggable tool
  5. Redux-form is far better than the conventional way of doing form related stuff.
  6. Redux Middlewares can make your job easy.

Cons of Redux

  1. Not recommended for small-scale applications
  2. Very complex and high implementation cost
  3. Needs to be injected as a dependency
  4. Very high cost just to add a small feature
  5. Integration of React’s modules may require alteration and needs to be binded with the redux state.
  6. In order to make a big component reusable, the data needs to be passed at each level of the hierarchy of the tree which is cumbersome but this can be resolved with the context API integration along with Redux.

Redux should be avoided for smaller applications, why?

The main problem with Redux is the complexity that’s why it is only recommended for mid to large scale applications. Even for a small addition in the product, a developer would have to write good amount of code. So for smaller applications, a developer would have to write tons of lines of code to set up the architecture and further add features on it.

What is Context API?

Context API is a great tool which has now been officially stabilised and is used to transfer your component’s state from any higher level component to any lower level component. Conventionally what happens is we would have to transfer the state from the higher level components to the lower level components at each level. Following is a diagram for better understanding:

Pros Of Context API

  1. Scalable from any range of application (small, mid, large)
  2. Comparatively less complex than Redux
  3. Implementation cost is lower
  4. No need to pass data to the children at each level. Consumer component instance can access all the data provided by the Provider Component at any level.
  5. Core part of React JS library so no need to import any additional libraries thus dependencies are reduced.
  6. Code is easy to maintain and very reusable.
  7. Integration of React’s modules is seamless

Cons Of Context API

  1. Libraries such as Redux-form which has an excellent integration with React + Redux. So Redux needs to be integrated to use redux-form.
  2. Middlewares need to be written as a custom code.
  3. A bit harder to debug.

Why and When to choose Context API?

We can make our front-end architecture similar to Redux Architecture and it would offer the same benefits which Redux offers but not completely. Using context is not such a big coding effort and new features can be included with a bit more effort than usual but that would completely worth it. I would definitely recommend using the Context API no matter how small or big a product is. So using Context API is completely independent if we are using Redux or not and you can simulate the behaviour of Redux with Context.

Context API / Redux

The main purpose of Redux is to have a central repository of all the states in the app but if that could be accomplished with Context API which now comes as a core part of React Library, that would be great. We can write some code to accomplish the Redux architecture with Context API.

How Context API works?


Context API provides us some objects which is used to wrap our JSX template with some values and corresponding callbacks. The object is created as

const context = React.createContext();
const {Provider, Consumer} = context;

This context object has two parts {Provider, Consumer}. Provider is an object which acts as a data/state provider and this data would be consumed by the Consumer object wrapping our React Component Template. Now the consumer component can make use of the data for representation and corresponding callbacks to manipulate the data. It would be more clear with an example.
Well, Redux works in the same fashion. It takes up a state/data from the store and gives them to a component in form of props. The data passed to the component is further manipulated by the callbacks provided by the Smart Components (Injected with the callbacks).

Example

  1. Download and setup a demo project from the create-react-app and the project structure will look like below

  2. We will create all of our contexts inside /src/context (new directory).

  3. Create AppContext.js inside /src/context and add the necessary state data in the Provider and export the whole context

  4. There is one thing that you need to keep track of is you will have to use the same instance of the context for the consumer. Otherwise, that would create it as a completely separated instance and you won’t receive your data from the Provider. The same needs to be exported and imported to have the consistency.  

  5. Now we have created the RootContext i.e AppContext, Wrap our App Component being imported in the index.js inside the Provider with the state provided in the AppContext and Consumer will come into the play for wrapping up the actual template i.e App.js , where data/functions will be used from the Provider to create the Rich UI.

  6. To explain the example, I am providing the state in the Provider as 

    this.state = { age: 23, setAge: this.setAge };

    where this.setAge is a function changing the age in the state with the value provided as arguments
    Code: https://github.com/vishalchandna1/react-example/blob/context-api-redux/src/context/AppContext.js 

  7. Now we can make use of this data whereever we want and independent of the tree. we just need to use the Consumer from the AppContext as 

    <AppContextConsumer>
      {values => return <Fragment>
        Age: {values.age} 
       <button onClick={values.setAge.bind(this, values.age + 1}>
         Increase by 1
       </button>
      </Fragment>}
    </AppContextConsumer>


    Code: https://github.com/vishalchandna1/react-example/blob/context-api-redux/src/App.js 

  8. That’s it and you are done.

To have a closer look at the code repo (Branch -> context-api-redux) https://github.com/vishalchandna1/react-example/tree/context-api-redux 

Now if you closely observe the code then you will know that it is acting pretty much similar the Redux architecture but a bit more advanced. With the help of Context API, we can build as much stateless components as much as we want. 

The true advantage of using contexts is you don’t have to pass the state at each step. Just create a Provider and the state passed will be available to any level children with the help of Consumer Component of the same instance.

How Context API can replace Redux?

As you have seen Context API is very similar to the Redux but a bit advanced and comparatively less complex. You can create the modular contexts for your React Components and wrap one inside the other. React doesn’t care about how you are passing the data to the components, the thing of consideration is how simple, efficient and reusable it is. 

Just like redux, with multiple state object merging into one single object, providing us a with a store, we can do the same with Context API but with much more flexibility. There are certain coding patterns that you can use Context API as your store but you can always create your own. I would definitely recommend you guys to look out for the coding patterns available for the Context API as it would give you a much bigger scope and how things can be made more reusable.

Hybrid Approach?

As Context API is a core part of the React Library so it wouldn’t take much sweat to integrate it with Redux which I personally consider to be ideal for mid to large scale applications. For small applications Context API can handle it just fine. I just love Redux-form library but I couldn’t use it without Redux which is a big pain. What do I recommend to be more productive? Integrate Redux with Context where all of the states will be managed and manipulated by the Redux but for the internal working of the component, Context API should be used which would provide an edge when passing props to the lower level components thus accessible at any level. It would be a very seamless integration and no overhead at all.