Props and Prop Drilling in React

When you first start working with React, everything feels surprisingly clean. But the moment your app grows beyond 5-6 components, you suddenly find yourself passing the same data through multiple layers just to reach one child component. 


That’s where most beginners hit their first real frustration with prop drilling. Your code starts feeling messy, harder to read, and difficult to maintain. This problem is called prop drilling in React, and almost every React developer faces it at some point. 


In this blog, we will explore the basic use of props, understand what is prop drilling in React, why React prop drilling is problematic, and how to avoid it. 

What are Props in React?

Before understanding Prop drilling, you must first understand Props clearly, because everything starts here. In React, props (short for properties) are simply a way to pass data from one component to another. 


Think of props like function arguments. Just like you pass values to a function, you pass data to a component using props. This allows components to stay reusable, dynamic, and clean instead of hardcoding values everywhere. 


Here is a simple example: 

function Greeting(props) {

  return <h2>Hello, {props.name}</h2>;

}


function App() {

  return <Greeting name="Akshay" />;

}


  • <App> is the parent

  • <Greeting> is the child

  • <”Akshay”> is passed as a prop

  • Child receives it using props.name


The output is: 

Hello, Akshay


Props are important in React as they make your app: 


  • Reusable: same component, different data

  • Dynamic: UI updates based on input

  • Maintainable: Avoids duplicate code

  • Predictable: One-way data flow (top>down)


<UserCard name="Rahul" />

<UserCard name="Priya" />

<UserCard name="Aman" />

What is Prop Drilling?

In an app, your data lives in the top-level component (usually <App>), but the component that actually needs it is buried 2-4 levels deep. Since React follows a one-way data flow (parent > child), you have only one option: to keep passing the same prop down through every intermediate component. 


This repeated forwarding of props through components that don’t even use them is called props drilling in React. In layman’s terms:


Prop Drilling is passing props through multiple unnecessary layers just to reach a deeply nested component. 


Let’s say your component tree looks like this: 

App

 └── Dashboard

      └── Sidebar

           └── Menu

                └── ProfileButton


Now suppose only <ProfileButton> needs the <username>. Now, because of React prop drilling, you must do this: 


function App() {

  const userName = "Akshay";


  return <Dashboard userName={userName} />;

}


function Dashboard({ userName }) {

  return <Sidebar userName={userName} />;

}


function Sidebar({ userName }) {

  return <Menu userName={userName} />;

}


function Menu({ userName }) {

  return <ProfileButton userName={userName} />;

}


function ProfileButton({ userName }) {

  return <button>{userName}</button>;

}


The problem here is that the: 


  • <Dashboard> does not use <username>

  • <Sidebar> does not use it

  • <Menu> does not use it

  • They are just forwarding it


This is exactly what is Prop drilling in React. Unnecessary prop passing through layers that don’t need the data. For small apps, this is manageable. But once your project grows, props drilling quickly turns your code into a mess. 

Why Prop Drilling is a Challenge?

At first, prop drilling does not look like a big deal. Passing one or two props feels normal. But as your app grows, reach prop drilling slowly turns into a maintenance nightmare. 


In real-world projects like dashboards, eCommerce apps, or admin panels, this leads to confusing code and hours wasted debugging. That’s when props drilling in React stops being a small inconvenience and becomes a serious architectural problem. 

1. Poor Readability

When every component keeps forwarding props, your code becomes noisy. 


<Sidebar userName={userName} theme={theme} cart={cart} isLoggedIn={isLoggedIn} />


Now imagine passing 8-10 props like this through 4 levels. It becomes: 


  • Hard to read

  • Hard to understand what’s actually used

  • New developed get confused instantly

2. Tight Coupling Between Components

With props drilling React, middle components become dependent on props they don’t even need. Here is an example: 


function Sidebar({ userName }) {

  return <Menu userName={userName} />;

}


If you remove or rename <username>, suddenly: 


  • Sidebar breaks

  • Menu breaks

  • Dashboard breaks


This creates unnecessary dependencies, which is bad design. 

3. Difficult Debugging

For beginners, this is a real concerning challenge. When something breaks, you start asking: 


  • Where did this prop come from?

  • Who passed it?

  • Why is it undefined?


Then you keep jumping between ProfileButton > Menu > Sidebar > Dashboard > App

4. Scalability Problems

While prop drilling is somewhat manageable in small apps, it becomes chaotic as your app scales. When your app grows, it has more shared data, more nested components, and more prop passing. At some point, React props drilling becomes unmanageable, and your codebase feels like an intertwined puzzle. 

How to Avoid Prop Drilling in React?

Passing props through 4-5 layers just to reach one component is not smart engineering; it’s extra work for both your brain and your codebase. That’s why modern React apps use better patterns that allow data to be shared directly without unnecessary middlemen. Here are the most practical solutions: 

1. Lift State Only Where Necessary

Before jumping into advanced tools, sometimes the fix is just better component design. If two sibling components need the same data, don’t pass props down 4 levels. Move the state to their closes common parent. 


Bad Structure: 

App → Dashboard → Sidebar → Menu → Button


Better Structure: 

App → Button

App → Sidebar


This approach alone solves many beginner mistakes. 

2. Use React Context API

This is the official solution for avoiding prop drilling in React. The Context API lets you share data globally without manually passing props through every level. Here’s how to do it: 

Step 1 - Create Context

import { createContext } from "react";


export const UserContext = createContext();

Step 2 - Provide Data at Top Level

function App() {

  const userName = "Akshay";


  return (

    <UserContext.Provider value={userName}>

      <Dashboard />

    </UserContext.Provider>

  );

}

Step 3 - Consumer Directly Where Needed

import { useContext } from "react";

import { UserContext } from "./UserContext";


function ProfileButton() {

  const userName = useContext(UserContext);


  return <button>{userName}</button>;

}


This approach is better because there are no forwarding props, no unnecessary coupling, cleaner components, and easier debugging. Even if <ProfileButton> is 10 levels deep, it directly accesses data. 

3. Use State Management Libraries 

For large production apps (dashboards, SaaS tools, and eCommerce), Context may still feel limited. Developers use various tools to centralize state and eliminate React props drilling at scale, like:


  • Redux

  • Zustand

  • Recoil

  • Jotai

Final Words

If you look back at your React learning journey, props probably felt like the easiest concept at the start. You just pass the data from parent to child, and you are done. But as soon as your app grows even slightly bigger, constant prop drilling starts slowing you down. Suddenly, half your components are just forwarding values they don’t even use, and your clean project begins to feel messy for no reason. 


However, the truth is that props are perfect for small and direct communication, but not for deep or global data sharing. Most beginners try to manage prop drilling. But true experts simply avoid it altogether. 

Frequently Asked Questions(FAQs)

Q1. What is prop drilling in React?


Ans. Prop drilling in React refers to the process of passing data from the parent component down through multiple intermediate components to reach a deeply nested child component. These middle components often do not use the data themselves and simply forward it. This creates unnecessary complexity and makes the code harder to manage as the application grows. 


Q2. Why is prop drilling considered a bad practice?


Ans. Prop drilling is not technically wrong, but it becomes problematic in medium to large applications. It reduces readability, increases coupling between components, and makes debugging more difficult. When many components depend on props that they do not actually use, even small changes can break multiple parts of the app, slowing down development and maintenance. 


Q3. How do you avoid prop drilling in React?


Ans. Props drilling can be avoided by restructuring the component tree so data is closer to where it is needed or by using the Context API to share values directly across components. For larger applications, state management solutions like Redux or Zustand help centralize data and remove the need for repeated prop passing altogether. 


Q4. When should I use Context instead of props?


Ans. Props work best when data only needs to travel one or two levels down. When multiple deeply nested components need access to the same information, Context becomes a better option. It reduces unnecessary forwarding and keeps components cleaner, which improves both scalability and maintainability.

Discover More Courses on Skillwaala