Definiton - “useContext” hook is used to create common data that can be accessed throughout the component hierarchy without passing the props down manually to each level
Before reading this article, you should be aware of components, props, and states in React. I have explained these in my article revising react basics.
Now let’s get started.
First, let’s think if you want to pass the data from parent to child, what did you use? Correct, Props. But what if, you have a tree kind of structure where you want one parent, then child, then sub child, and so on.
From the above image, let’s say you wannt to pass data from the <App/> component which is a parent component to the sub child component <C/>. Can you do that using props? Well, let’s try.
Passing data from parent to child props
App.js
import A from "./Component/A"; import "./App.css"; function App() { return ( <> <A name="himanshu" /> </> ); } export default App;
A.js
import B from "./B"; const A = () => { return ( <div> <p>A</p> <B nameB={props.name} /> </div> ); }; export default A;
B.js
import C from "./C"; const B = () => { return ( <div> <p>B</p> <C nameC={props.nameB} /> </div> ); }; export default B;
C.js
const C = (props) => { return ( <div> <p>My name is {props.nameC} </p> </div> ); }; export default C;
Output is :
I guess we got the output. Yes, we have successfully passed the data from the top component to the bottom component, but wait, is it right? NO
2 reasons why the above approach is incorrect
- Every time you need to pass the data down the hierarchy, it has to unnecessarily pass to all the child components, until we reach our component, which is not right. This is known as prop drilling. If the data is huge, this will affect the coding efficiency.
- If any of the child components break, the whole child component will break, thus making it highly dependent and volatile.
How to fix it? By using useContext()
What is useContext()
In short , Context APIs enable us to define the context Object which stores some data and will make it available throughout the hierarchy without passing the data as props.
Also useContext is inbuilt in react, so no need to install any external package for that.
Defining contextAPI (useContext())
Before you get confused between contextAPI and useContext() hooks , let me clear that.
Before useContext hook , context API was implemented as –
- createContext
- Provider
- consumer
But the consumer was a bit lengthy and complex, hence Consumer has been replaced by useContext() hooks.
- createContext
- Provider
- useContext()
How to implement content API to your application?
Step 1 – Create a context instance
const BioData = createContext();
Note - createContext() needs to be imported first
import { createContext } from "react";
Step 2 – Wrap the child component the provided and pass the value which needs to be sent to the below hierarchy
<BioData.Provider value={"himanshu"}>
<A />
</BioData.Provider>
Step 3 – Export the provider
export { BioData };
Step 4 – Pass the provided value to the nested child component using useContext() hooks
import React, { useContext } from "react"; //useContext() hook imported
import { BioData } from "../App"; //import the exported provider instance
const C = () => {
const dataContext = useContext(BioData); //pass the Provider value to useContext hooks and return it below
return (
<div>
<p>My name is {dataContext}</p>
</div>
);
};
Note – We need to implement logic only at 2 components, 1 – parent or the main component where the data(props or state value) actually is and 2 – child component where we need to use that data
Now that we have understood context API, let’s implement it in our code.
App.js
import { createContext } from "react"; import A from "./Component/A"; import "./App.css"; const BioData = createContext(); function App() { return ( <> <BioData.Provider value={"himanshu"}> <A /> </BioData.Provider> </> ); } export default App; export { BioData };
C.js
import React, { useContext } from "react"; import { BioData } from "../App"; const C = () => { const dataContext = useContext(BioData); console.log(dataContext); return ( <div> <p>My name is {dataContext}</p> </div> ); }; export default C;
- In the above example, we have wrapped the main component A (after the Parent component <App/>) with provided
- And now the provided {biodata} is available with a value=”Himanshu” to be used below In any nested child component
Conclusion
useContext() is a way to stop prop drilling in your application and making state centralized to that the value to state can be used to any nested child component without having to pass down the prop to each and every component. It makes your application efficient and reduces complexity.
Alternative to context API is Redux, we will talk about it in some other article.
Thank you for reading.