DEV Community

Cover image for Why Prop Drilling Makes Your React Code Messy
Manish Kumar
Manish Kumar

Posted on

Why Prop Drilling Makes Your React Code Messy

You start with a simple React app, everything is clean, and then suddenly you're passing props through five components to get some data where it needs to go. It's like being forced to pass a message through people who don't need to hear it.

What's Prop Drilling?

Basically, it's when you pass props through multiple components that don't even need them, just to get the data to a deeply nested child component. Think of it like this:

// Parent has the data
function App() {
  const user = { name: "John", email: "john@example.com" };
  return <Header user={user} />;
}

// Header doesn't need user data, but passes it down
function Header({ user }) {
  return <Navigation user={user} />;
}

// Navigation doesn't need it either, but keeps passing
function Navigation({ user }) {
  return <UserProfile user={user} />;
}

// Finally, someone who actually needs it
function UserProfile({ user }) {
  return <div>{user.name}</div>;
}
Enter fullscreen mode Exit fullscreen mode

See the problem? The header and navigation are just middlemen doing nothing useful.

Why It's Actually Bad

  1. Your components become tightly coupled: Every component in the chain now depends on props it doesn't care about. Change the user object structure? Good luck updating 4 components.

  2. It's hard to maintain: Want to add a new property? You'll be editing multiple files. Want to remove something? Same story. It's tedious.

  3. Your code becomes harder to read: Looking at the Header component, you'd think it cares about user data. But it doesn't. It's just noise.

  4. Testing becomes painful: Now you need to mock props in components that don't even use them. Your test setup gets unnecessarily complex.

Better Solutions

Context API for shared state:

const UserContext = createContext();

function App() {
  const user = { name: "John", email: "john@example.com" };
  return (
    <UserContext.Provider value={user}>
      <Header />
    </UserContext.Provider>
  );
}

function UserProfile() {
  const user = useContext(UserContext);
  return <div>{user.name}</div>;
}
Enter fullscreen mode Exit fullscreen mode

State management libraries: Redux, Zustand, or even simple custom hooks can help you avoid this mess.

The Reality Check

I'm not saying never pass props down one level. That's normal. But when you're going 3+ levels deep and components in the middle don't care about the data, that's when you know you need to refactor.

The goal isn't to avoid props entirely. It's to make your code more maintainable and easier to reason about. Trust me, future you will thank present you for not creating a prop-drilling nightmare.

Top comments (0)