Before starting this blog, I assume that you all should have basic knowledge about React.
In this blog we are going to learn one of the best concept of React - Prop Drilling and Context API.
Introduction
Prop drilling is a method where we pass a props with another component with the help of all the components that come between them.
Let us understand with a real life example.
Imagine you are in school and you are sitting on the last bench and your best friend is sitting on the first bench. Suddenly your best friend needs a pen and you have a spare pen and you want to give that pen to your best friend. For this, ask your friend sitting on your next bench to take the pen and forward it to the next one and said that repeat this until the pen reaches your friend.
Here you can see how he gives a pen to his best friend with the help of another bench.
In React also if we want to pass props to any other component then we have to pass props to all the components which come between them and This whole process is known as React Prop Drilling.
Now come and understand all these things with the help of code.
import React, { useState } from "react";
//FIRST COMPONENT
const LastBench = () => {
const [penName, setPenName] = useState("Blue Gel Pen");
return (
<>
<h1>Hello I am Last Bench</h1>
</>
);
};
//SECOND COMPONENT
const NextBench = () => {
return (
<>
<h1>Hello I am Next Bench.</h1>
</>
);
};
//THIRD COMPONENT
const FirstBench = () => {
return (
<>
<h1>Hey I am First Bench</h1>
</>
);
};
export default LastBench;
In the above code you see that we create 3 components. In the first component we declare a pen name with the help of useState hook. Now we have to pass the pen name to the last component with the help of second component
import React, { useState } from "react";
//FIRST COMPONENT
const LastBench = () => {
const [penName, setPenName] = useState("Blue Gel Pen");
return (
<>
<h1>Hello I am Last Bench</h1>
<br />
<NextBench penName={penName} />
</>
);
};
//SECOND COMPONENT
const NextBench = ({ penName }) => {
return (
<>
<h1>Hello I am Next Bench.</h1>
<FirstBench penName={penName} />
</>
);
};
//THIRD COMPONENT
const FirstBench = () => {
return (
<>
<h1>Hey I am First Bench</h1>
</>
);
};
export default LastBench;
We call second component in first component then we pass props with penName And then we repeat all these things in second component. We call the last component, then we pass the props named penName.
import React, { useState } from "react";
//FIRST COMPONENT
const LastBench = () => {
const [penName, setPenName] = useState("Blue Gel Pen");
return (
<>
<h1>Hello I am Last Bench</h1>
<br />
<NextBench penName={penName} />
</>
);
};
//SECOND COMPONENT
const NextBench = ({ penName }) => {
return (
<>
<h1>Hello I am Next Bench.</h1>
<FirstBench penName={penName} />
</>
);
};
//THIRD COMPONENT
const FirstBench = ({ penName }) => {
return (
<>
<h1>Hey I am First Bench</h1>
<h4>{penName} Here i got My Pen</h4>
</>
);
};
export default LastBench;
Now You can see Above code we Finally use props in last component which we declared in first component. In second component we have passed props now we can use that props in third component.
This is how React Prop Drilling Work.
But you can see in the code that the props we use in second components are useless. They don't need that props, but we pass that props for use in the third component.
It's just like you bother the next bench to pass the pen to the first bench.
To avoid all this, we use the Context API. It works like you called the teacher and requested him/her to give this pen to his friend who are sitting on the first bench.
Now let's refactor the above code with the Context API and the useContext hook.
We have to create an object with React.createContext() in global. Each context object comes with a provider component that assigns a value to the context object. To add that value we have to pass "value" attribute with them
import React, { useState, useContext } from "react";
//FIRST COMPONENT
const TeacherContext = React.createContext();
const LastBench = () => {
const [penName, setPenName] = useState("Blue Gel Pen");
return (
<>
<h1>Hello I am Last Bench</h1>
<br />
<TeacherContext.Provider value={{ penName }}>
<NextBench />
</TeacherContext.Provider>
</>
);
};
//SECOND COMPONENT
const NextBench = () => {
return (
<>
<h1>Hello I am Next Bench.</h1>
<FirstBench />
</>
);
};
//THIRD COMPONENT
const FirstBench = () => {
return (
<>
<h1>Hey I am First Bench</h1>
<h4>Here i got My Pen</h4>
</>
);
};
export default LastBench;
In above code you see that we create an object named TeacherContext with the help of React.createContext() and use that object with Provider component with value attribute in first component, where we create a props with name PenName.
Now we need to pass the props to our last component directly. For that we need "useContext" keyword.
import React, { useState, useContext } from "react";
//FIRST COMPONENT
const TeacherContext = React.createContext();
const LastBench = () => {
const [penName, setPenName] = useState("Blue Gel Pen");
return (
<>
<h1>Hello I am Last Bench</h1>
<br />
<TeacherContext.Provider value={{ penName }}>
<NextBench />
</TeacherContext.Provider>
</>
);
};
//SECOND COMPONENT
const NextBench = () => {
return (
<>
<h1>Hello I am Next Bench.</h1>
<FirstBench />
</>
);
};
//THIRD COMPONENT
const FirstBench = () => {
const { penName } = useContext(TeacherContext);
return (
<>
<h1>Hey I am First Bench</h1>
<h4>{penName} Here i got My Pen</h4>
</>
);
};
export default LastBench;
We can see in the above code that the โuseContextโ keyword will make the first component props available to the last component and in last we use that prop in our component.
Conclusion
We pass the value of the first component to the last component without disturbing the other components with using useContext hook.
Let's Connect With Me
Thank You for reading this blog ๐
I hope all of you have benefited after reading this blog ๐
Do Share it with your friends and family and get them benefit from it too ๐งก๐
Here You Connect with me https://connect.rishavraj.codes/
Top comments (1)
I have an easier solution. Create some folder structure such as src/context/PenContext.js, and inside the PenContext file import createContext function and write:
export default PenContext = createContext( { penName: "Blue Gel Pen" } );
FirstBench component can now import PenContext and use it as in
const penContext = useContext(PenContext)
.That's all, it just works without ever using the Provider wrapper around anything. In case the pen's name had to be changed in FirstBench, it can always be easily modified by changing "penContext.penName".
Now, perhaps there's something I'm missing out on for not wrapping stuff in the Provider component? If so, please advise me, I'd be grateful.