Props Drilling In React?
Tags: react, javascript, webdev, beginners
Published: 2021-10-30 10:22:35

* what's props drilling?
* why to avoid it?
* How to dot that?

We are going to answer above questions to know about props drilling.
## What's props drilling?
![props drilling](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kexuxbpsruxbhdxidl6u.jpeg)
Passing props within a tree of components is known to be props drilling. Tree of components means when you pass prop from the root component _App_ to the parent component _Header_ of the child component _Search_.

> ***App(props) --> Header(props) --> Search(props)***

code for above example, shows how placeholder text is set upon the prop passed from root component.

```javascript
import React from 'react'

export default function App(){
   return(
       <div>
        <Header text="Search Movie..." />
       </div>
   )
}
function Header(props){
    return(
        <header>
            <Search text={props.text} />
        </header>
    )
}
function Search(props){
    return(
        <nav>
            <input 
                type='text'
                value=''
                placeholder={props.text}
            />
        </nav>
    )
}
```
> ***keep drilling until you reach the bottom.***

## Why to avoid?
Before knowing the answer, look at the following picture. 
![Dolls](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ouuagvu5pzb29yfhxk4k.jpeg)
It seems like every next doll is the child of previous doll, and you can hide all the dolls under the largest doll(root).

What if we want to put the coins in the last doll or in between? here's the catch! we will open the every doll until we open the wanted doll. 
So, is the case with components that to change the props in last component we will pass props through every parent component and re-render it. which is quite expensive. that's why we need to avoid this props drilling. 

## How to avoid?
hmmmm, how to avoid? Well what the logic says is that there should be a global value which must be accessed wherever wanted, right! That's how it is also resolved.

Need 3 things
* Context component
* Provider
* Consumer

***Context API*** is available to help us to provide and consume the context. Components accessing context will only be re-rendered.
Context component will be created by a built-in function of React `React.createContext()` function by default takes a value, whatever you provide it. 
![Context API vs props drilling](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oq9m2bfc6895mtyh7koi.png)
### Create context component
Make a new file, then export and import it.
```javascript
const Context = React.createContext('default value')
export default Context 
```
### Providing
import the context first, then provide to component you want, suppose we are providing to Header component.
```javascript
//import Context
<Context.Provider value='Search Movie...'>
   <Header />
</Context.Provider>
```
### Consuming
well context can be consumer by two way, either by React.Consumer or useContext() hook.
let's see the both
#### Context.Consumer
```javascript
//import Context first, if it's a separate file.
<Context.Consumer>
{context => <input type='text' value='' placeholder={context} /> }
</Context.Consumer>
```
#### useContext() hook
you have to import {useContext} or use as React.useContext, it takes Context as an argument and returns the value.
```javascript
<input type='text' value='' placeholder={useContext(Context)} />
```
### Complete code
 It's a functional component code so I have used hook.
```javascript
import React, {useContext} from 'react'

const Context = React.createContext('default value')
export default function App(){
   return(
       <Context.Provider value='Seach Movie...'>
            <Header />
       </Context.Provider>
   )
}
function Header(props){
    return(
        <header>
            <Search />
        </header>
    )
}
function Search(props){
    return(
        <nav>
            <Context.Consumer>
                {context => (
                        <input 
                            type='text'
                            value=''
                            placeholder={context}
                        />
                    )
                }
            </Context.Consumer>
        </nav>
     )
}
```
> ***Context API is the most common solution, but not the only.***

Let me know if it helped you or if there's anything missing.

>Join me on twitter @akramnarejo I keep sharing tips and resources about javascript, and react.