React all hooks series: Let' acquire the useContext hook.
Tags: javascript, react, redux, beginners
Published: 2022-02-01 07:57:13

Look! Every feature should solve a problem, so if you want to understand a new concept of a feature, then you have to figure out what problem it solves and how.

This is a journey to comprehend the problem with passing data using props and how Context API solve this problem. By the end of this tutorial will get the prize of acquiring the power of `useContext` hook.

Prerequisites? Basic ReactJS, know how to use  `useState()` hook, and to understand what are props.

That's it. Let's go.

#What is Context API?

Context provides a way to pass data through the component tree without having to pass props down manually at every level. We can implement it to work with global state and avoid props drilling. 

<img width="100%" style="width:100%" src="https://media.giphy.com/media/9uIjYTJCtMnHsMpbHW/giphy.gif">

Props drilling is when we are obligated to pass props to components that don't use them but their children do.



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4pm21fmga9xdxjwf0i4j.png)

In the above picture, we are obligated to pass the`name` state through the `Settings` component as a middle man to work with it in the `Profile` and `Shipping` components ( Maybe pass it to the Appearance component too if it has children that require the state "name").

Code example?



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bttty0kx0x1nh3yr4p0p.png)


In the `Home` component, we have the global state called `name`, consider it as a username. We pass the `name` and`setName` to the `Settings` component as props and transfer them again to the `Profile` and `Shipping` components.

Let's cut the middle man by using the Context API. 

First, we import `createContext` , initialize it with a null value, and export it :

```
import React, {useState, createContext} from 'react';
export const NameContext = createContext(null);
```

Next, we wrap the component we want to pass the data down to with a context `Provider`.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b182qdu7wm3l8xkxpwww.png)

Keep in mind that the `value` prop is required. Here, we are passing an object.

Now the `Settings` component is clean.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hu6kwz5jg7kcb99d2zrg.png)

"Profile" and "Shippings":


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/73ijtyhd3blz2yc7immj.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4n96p93y0jst0jz7pekt.png)

We import the `NameContext` we initialized before in `Home` , then we create a `Consumer` that wraps a function, the function takes an `obj` as a parameter ( it's the one we passed using the value prop) and return `JSX` with the state we want to render.

That was nice, right? I mean we cut the middle man (Settings component ). We no longer depend on it.

Our solution to props drilling is working but it's vulnerable.

Imagine if we have more that a global state to pass down the component tree.

<img width="100%" style="width:100%" src="https://media.giphy.com/media/mEV42F38lur6PbfapW/giphy.gif">

Let's create another state called currency. User's currency in use.

```
const [currency, setCurrency] = useState('USD')
```

We initialize a context for it.

```
export const CurrencyContext = createContext(null);
```

And then, pass it by wrapping the `Settings` component with the `currencyContext.Provider` :


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6zqspr70ujkujd2a1cld.png)

Let's use it in the `Shipping` component:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ycuqwzmjhhn1l99ib1rj.png)

Inside the `NameContext` consumer, we inject the `CurrencyContext` consumer with a function that returns the JSX which uses the state. 


It's hairy and ugly. 

<img width="100%" style="width:100%" src="https://media.giphy.com/media/hrpCvvpELwhN2JQZR9/giphy.gif">

We need to simplify it. Let's invoke the `useContext` hook.

#The Amazing useContext hook.

`useContext` is so simple to use. First, we import it:

```
import React, {useContext} from 'react';
```

Inside the `Profile` component, we initialize it with the name of the context as a value:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vv63k5f613xpon9vohi3.png)

Just like that, we use it inside our JSX. No nested functions and thus no ugliness.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6b3o592q8e7ghugel0fq.gif)

Congratualations, the journey has ended and you have acquired a new hook. Use it cleverly.

That was quite straight to the point, wasn't it?

See you in the next article…

Wait! 

I'll be glad if you share my article.