Why not prop drilling?


Prop drilling can be a good practice and for smaller apps and a bad practice for bigger apps; so what is prop driling?
Prop drilling refers to the practice of passing props through multiple levels of components that don't actually use these props, just to get them to components deeper in the hierarchy that need them. For example:
Parent → ChildA → ChildB → ChildC (needs the prop)
In the set up that I will provide, there is minimal prop drilling, I provide the home.tsx and IntroButton.tsx
'use client';
import React, { useState } from 'react';
import Image from 'next/image';
import Pet2 from '@/public/images/pet 2.png';
import VideoPopup from '@/components/ui/cards/Video_pop';
import IntroButton from '@/components/ui/buttons/VideoBtn';
const Home = () => {
const [isVideoOpen, setIsVideoOpen] = useState<boolean>(false);
const handleOpenVideo = () => {
setIsVideoOpen(true);
};
const handleCloseVideo = () => {
setIsVideoOpen(false);
};
return (
<div className="min-h-screen bg-[#FFF5E1] relative overflow-hidden">
<div className="max-w-screen-xl mx-auto px-4 py-8 md:py-24">
<div className="grid md:grid-cols-2 mt-[2rem] items-center">
<div className="mb-[2rem]">
<div className="mt-[4rem] md:p-[0.5rem]">
<h1 className="text-[#0A2342] text-xl md:text-3xl font-bold leading-tight">
One More Friend
</h1>
<h2 className="text-[#0A2342] text-xl md:text-3xl font-bold">
Thousands More Fun!
</h2>
<p className="text-gray-700 text-lg pt-2">
Having a pet means you have more joy, a new friend, a happy person who
will always be with you to have fun. We have 200+ different pets that
can meet your needs!
</p>
</div>
<div className="flex gap-4 mt-[2rem]">
<IntroButton onClick={handleOpenVideo} />
<button className="px-6 py-3 bg-[#0A2342] text-white rounded-full font-medium hover:bg-blue-600 transition-colors">
Get Started
</button>
</div>
</div>
<div className="relative">
<div className="relative z-10">
<Image
src={Pet2}
alt="Happy person with a Corgi dog"
className="w-full h-auto rounded-lg"
/>
</div>
</div>
</div>
</div>
<VideoPopup isOpen={isVideoOpen} onClose={handleCloseVideo} />
</div>
);
};
export default Home;
IntroButton.tsx
'use client';
import React from 'react';
import { FaPlay } from 'react-icons/fa';
interface IntroButtonProps {
onClick: () => void;
text?: string;
}
const IntroButton: React.FC<IntroButtonProps> = ({ onClick, text = 'View Intro' }) => {
return (
<div className="relative inline-block">
<span className="absolute inset-0 rounded-full animate-pulse bg-[#dc2626] opacity-90"></span>
<button
className="relative px-6 py-3 border-2 border-[#0A2342] text-[#0A2342] rounded-full font-medium hover:bg-[#0A2342] hover:text-white transition-colors flex items-center gap-2"
onClick={onClick}
>
{text}
<FaPlay className="w-4 h-4" />
</button>
</div>
);
};
export default IntroButton;
Is Prop Drilling Happening Here?
In this current setup, there's minimal prop drilling:
You're passing the
handleOpenVideo
function from Home to IntroButton. This is just one level of prop passing, which is normal and not considered problematic prop drilling.You're also passing the video state and handlers to the VideoPopup component, which is also normal component composition.
When Prop Drilling Becomes a Problem
Prop drilling becomes a problem in larger applications when:
You're passing props through many components that don't use them.
The same props need to be available in many different parts of your component tree.
You have to update many components whenever you change the structure of a prop.
Alternatives to Prop Drilling
If your application grows and prop drilling becomes unwieldy, consider these alternatives:
- Context API: React's Context API allows you to share values between components without explicitly passing props. This works well for app-wide state like themes, user authentication, etc.
// Create a context
const VideoContext = React.createContext({ isOpen: false, openVideo: () => {}, closeVideo: () => {} });
// Provider in parent component
<VideoContext.Provider value={{ isOpen, openVideo: handleOpenVideo, closeVideo: handleCloseVideo }}>
{children}
</VideoContext.Provider>
// Use in any child component
const { isOpen, openVideo } = useContext(VideoContext);
State Management Libraries: For more complex applications, libraries like Redux, Zustand, or Jotai can help manage global state.
Component Composition: Sometimes restructuring components can avoid the need for prop drilling.
Subscribe to my newsletter
Read articles from Hillary Nyakundi directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Hillary Nyakundi
Hillary Nyakundi
I am a software engineer who is fascinated with building exclusive technology.