How to use the React Context API
Tags: react, redux, javascript, typescript
Published: 2020-07-06 23:47:43


The new front-ends built with the most current frameworks have consequently generated greater complexities in what was previously only built with HTML + CSS + JS. Many terms and knowledge emerged in conjunction with these frameworks, one of which is the *state of the application*. Basically, each component that we build has a data in which it feeds and listens as its changes that are happening.

The concept of state took its due complexity when it was necessary to share the state of the application globally among the components of its application. For this, several libraries emerged, such as Redux, MobEx and etc. Redux, in theory, would be the most used library for this purpose among React programmers, and many of them find its usability terrible.

The React context API is a global state manager and is a feature recently implemented in the React ecosystem, being able to solve 90% of Redux solutions in an extremely simple way.

So, how about we learn how to use it today? Are you ready?

###**What is a context?**

The context, according to the dictionary, is defined as an interrelation of circumstances that accompany a fact or a situation. Our situation in the case, would be our components. Imagine that we are in a shopping cart and that cart needs to keep the state of the products on the cart screen when the cart is open, how much on the product listing page? How would we solve this?

####The old way

We could create several components and pass the data via props to each component. Thus, when the cart component is rendered, for each product click that the customer wishes **to add to the cart**, the cart component must be called again, changing its props, and within the cart itself, manage all these data that will be listened to by several different products on the page itself...

Whew! Only that? Did you find it complex?

#### With the Context API

We use a context that encompasses all components of the app, and whenever a product is added to the cart, the context will be updated and will notify all components. Thus, our cart only needs to pull information from the global context of the application.

Simple right?

####A picture is worth a thousand words

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nfdmezedooow2m0clyh3.png)

Knowing that, without the context, we need to pass in a chained way, each of the data, and without it, the context encompasses all the components at once.

###**Ready to code?**

We are going to build an e-commerce application using the *create-react-app*. For this, we need a cart component and a list component with the products. We need the *state to be shared between the two* so that one knows what the other knows.

####**Creating the context**

The first thing we need to do is to define our context. To do this, we created next to our **App.js** file a file called **AppContext.js**. And we will import, in addition to our common dependencies like useEffect and useState, useContext and it will do all the magic.

To define a context, we use useContext as shown below:

```javascript
import React, { useState, useEffect, createContext } from 'react';

export const AppContext = createContext();

```

####**Creating the state**

With this, we create a context that will wrap the entire App. With the context created, we will create in it the state of our cart through useState:

```javascript
export const Provider = (props) => {
  const [cart, setCart] = useState([]);
}
```

####**Returning the context**

Finally, with the state created, we will now have to make the state available to the components within the App. We do this with a return function as follows:

```javascript
  return (
    <AppContext.Provider value={[drivers, setDrivers]}>
      {props.children}
    </AppContext.Provider>
  )
```

Our **AppContext.js** file will be like that:

```javascript
import React, { useState, useEffect, createContext } from 'react';

export const AppContext = createContext();


export const Provider = (props) => {
  const [cart, setCart] = useState([]);

  return (
    <AppContext.Provider value={[cart, setCart]}>
      {props.children}
    </AppContext.Provider>
  )
}

```

###**And now, what do we need?**

With our context created, just import it into **App.js** and that's it, you can use it now. See below how:

```javascript
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import Routes from './routes';
import { Provider } from './AppContext'

function App() {
  return (
    <Provider>
      <BrowserRouter>
        <Routes />
      </BrowserRouter>
    </Provider>
  );
}

export default App;
```

Assuming that our components are in the Router Dom, automatically with the Provider, we can make them listen to the global state.

###**And how do I call the state in my component?**

Let's imagine that we are in the **Cart.js** component. What will we do to call the state context? Just insert the code below:

```javascript
import React, { useContext } from 'react'
import { AppContext } from '../../AppContext'

export default function Cart() {
  const [cart, setCart] = useContext(AppContext)
}
```

Done! Our Cart can now use the functions it would normally use in its internal state. Each time you call *setCart()* the entire App will hear these changes, without the need for Reducers, nor Actions, nor Dispatch, or anything like that. Simple isn't it?
 
**Remember that you can have numerous contexts within the same application.**

Thanks for reading!