DEV Community

Cover image for What is React Prop Drilling and Context API
Rishav Raj
Rishav Raj

Posted on

What is React Prop Drilling and Context API

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.

react

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.
Drill

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.
Class
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;

Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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.
Api

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;
Enter fullscreen mode Exit fullscreen mode

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.

context

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;
Enter fullscreen mode Exit fullscreen mode

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

done
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

connect

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)

Collapse
 
seljumnik profile image
mislavmatijevic

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.