Initially when I started working with react at beginning of the build, code would look super clean, and totally readable but as time passed things would become too complex mostly around props, sometime I would need a visual aid to understand the flow of the props π . This loop of passing props from one component to another created a lot of chaos for larger applications, and there is term for this process it’s called – Prop Drilling.
Wont it be much more simpler if you had all your props available globally ? π€

Now prop drilling is not the best practice, instead there are multiple tools and packages that can help you with managing your props, today we will be discussing about Context APIs.
What is a Context API?
Using context API you can easily pass data to different components without passing props manually at every level.
How to leverage Context?
#app.js
class App extends Component {
state = {
counter: 0
}
handleIncrement = () => {
const counter = this.state.counter
this.setState({counter: counter+1})
}
handleDecrement = () => {
const counter = this.state.counter
this.setState({counter: counter - 1})
}
render() {
return (
<div className="App">
<Counter counter={this.state.counter} increment={this.handleIncrement} decrement={this.handleDecrement} />
</div>
);
}
}
export default App;
#counter.jsx
const Counter = ({counter, increment, decrement}) => {
return (
<div className="container">
<span>{counter}</span>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
<Mocker counter={counter}/>
</div>
);
}
#Mocker.jsx
const Mocker = ({counter}) => {
return (
<div>
<h1>{counter}</h1>
</div>
);
}
export default Mocker;
Let’s go through the code βοΈ we have 2 components Counter and Mocker.

So in your App.js you will have a counter prop along with some handlers, this counter prop is then passed to the Counter component along with the handler ref. Next we need this value to also be passed to the Mocker component so we pass it as a prop.
Now, lets take a look at the steps we need to take to access the ‘counter’ state globally instead of passing it as a prop.
- Create the context
We can create context like this: const CounterContext = React.createContext(0) - PROVIDE CONTEXT VALUE
To provide value for the context first wrap the component in between the context provider and pass values, code will look similar to this:
<CounterContext.Provider value={{counter, increment, decrement}}> <Counter /> </CounterContext.Provider>
- CONSUME CONTEXT VALUE
To consume this in your component
const { counter, increment, decrement} = React.useContext(CounterContext)
Final code will look something like this
#app.js
import './App.css';
import React, { Component } from 'react';
import Counter from './components/counter';
const CounterContext = React.createContext(0)
const App = () => {
const [counter, setCounter] = React.useState(0)
const increment = () => setCounter(counter + 1)
const decrement = () => setCounter(counter - 1)
return (
<div className="App">
<CounterContext.Provider value={{counter, increment, decrement}}>
<Counter />
</CounterContext.Provider>
</div>
);
}
export {CounterContext}
export default App;
#Counter.js
import React, { Component, useState } from 'react';
import {CounterContext} from '../App'
import Mocker from './mock'
const Counter = () => {
const { counter, increment, decrement} = React.useContext(CounterContext)
return (
<div className="container">
<span>{counter}</span>
<button onClick={() => increment()}>increment</button>
<Mocker counter={counter}/>
</div>
);
}
export default Counter;
So we could easily integrate our code with context apis, let me know if this helped π€©