Suggest an editImprove this articleRefine the answer for “What is "prop drilling"?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Prop drilling** is the process where data (`props`) is passed down the component tree through several intermediate levels that don't use this data themselves, but simply "pass it further". **Key point:** if a prop passes through more than 2 levels, it's worth considering context.Shown above the full answer for quick recall.Answer (EN)Image## Definition **Prop drilling** is the process where **data (props)** is passed **down the component tree** through several intermediate levels **that don't use this data themselves**, but simply "pass it further". --- ## A simple example Suppose you have the structure: ```javascript <App> └── <Parent> └── <Child> └── <Grandchild> ``` You want to pass data from `App` -> to `Grandchild`. ### Without context (through props): ```javascript function Grandchild({ user }) { return <p>Hello, {user.name}!</p>; } function Child({ user }) { return <Grandchild user={user} />; } function Parent({ user }) { return <Child user={user} />; } export default function App() { const user = { name: "Tim" }; return <Parent user={user} />; } ``` Here `Parent` and `Child` **don't use** `user` **at all**, they simply **pass it further**. This is **prop drilling**. --- ## Why this is bad | Problem | What happens | |---|---| | Code noise | Every intermediate component is forced to have extra props | | Hard to maintain | Changing the structure requires changing every level | | Isolation decreases | Components become dependent on data they don't use | | Reusability drops | "Dumb" components are forced to know about unnecessary props | | Hard to read | The "chain" of props makes the app's logic harder to understand | --- ## Illustration ```javascript App ├── user (stored here) ↓ Parent ↓ Child ↓ Grandchild (uses it) ``` The whole tree is "drilled" with props from top to bottom - hence the term **"drilling"**. --- ## A more realistic example ```javascript <App> <Navbar /> <Sidebar /> <Main> <PostList> <PostCard user={user} /> </PostList> </Main> </App> ``` If `user` is only needed in `PostCard`, but has to be passed through `Main` and `PostList`, that's already **prop drilling hell**. --- ## How to solve the prop drilling problem ### 1. **React Context API** The most standard way to get rid of drilling is to create a "global data source". ```javascript import { createContext, useContext } from "react"; const UserContext = createContext(null); function Grandchild() { const user = useContext(UserContext); return <p>Hello, {user.name}!</p>; } function App() { const user = { name: "Tim" }; return ( <UserContext.Provider value={user}> <Grandchild /> </UserContext.Provider> ); } ``` Now `Grandchild` gets `user` **directly from context**, not through a chain of props. --- ### 2. **State management (Redux, Zustand, Jotai, Recoil)** If there's a lot of data and it's needed in different parts of the app, it's better to move it into a global store: ```javascript // store.js (example with Zustand) import { create } from "zustand"; export const useUserStore = create(set => ({ user: { name: "Tim" }, setUser: (user) => set({ user }), })); // Grandchild.jsx import { useUserStore } from "./store"; function Grandchild() { const user = useUserStore(state => state.user); return <p>Hello, {user.name}!</p>; } ``` Now there's no need to "drill" props - data is accessible from any component. --- ### 3. **Custom hooks** If context or Zustand feel like "heavy artillery", you can simply make a **custom hook** to hide the passing: ```javascript function useUser() { const [user, setUser] = useState({ name: "Tim" }); return { user, setUser }; } function App() { const userStore = useUser(); return <Parent userStore={userStore} />; } function Grandchild({ userStore }) { const { user } = userStore; return <p>{user.name}</p>; } ``` Cleaner than passing every individual prop, but prop drilling remains - just simplified. --- ### 4. **Composition instead of props** Sometimes you can pass components directly through children: ```javascript function Layout({ header, footer }) { return ( <div> <header>{header}</header> <main>Content</main> <footer>{footer}</footer> </div> ); } function App() { return ( <Layout header={<Header user={{ name: "Tim" }} />} footer={<Footer />} /> ); } ``` This doesn't remove prop drilling globally, but it **makes data passing local** and more manageable. --- ## When prop drilling is acceptable You don't always need to avoid it at any cost. If the component tree is shallow (1-2 levels). If the prop is only needed a bit lower. If there isn't much data and it rarely changes. **Context and a store are needed when the problem is systemic, not occasional.** --- ## Summary | Criterion | Prop drilling | |---|---| | What it is | Passing props through a chain of intermediate components | | Why it's bad | Pollutes the code, reduces isolation and reusability | | When it's acceptable | For shallow and simple cases | | How to solve it | Context API, Zustand, Redux, custom hooks | | Main rule | "If a prop passes through more than 2 levels, think about context" | --- **Main idea:** > **Prop drilling** is when data is drilled through unnecessary components. > The solution is to move the data source higher up and give direct access to it.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.