Use component composition to avoid passing props through layers that don’t need them. It makes components cleaner, more reusable, and easier to maintain.
Prop drilling happens when you pass data through components that don’t actually use it — just to reach deeper ones.
Example (problematic):
function App() {const [count, setCount] = useState(0)return <Child count={count} increment={() => setCount(c => c + 1)} />}function Child({ count, increment }) {return <GrandChild count={count} onIncrementClick={increment} />}
Here,
Childdoesn’t usecountorincrement— it just forwards them.
Instead of passing data, pass elements.
function App() {const [count, setCount] = useState(0)return (<ChildgrandChild={<GrandChildbutton={<button onClick={() => setCount(c => c + 1)}>{count}</button>}/>}/>)}function Child({ grandChild }) {return <div>{grandChild}</div>}function GrandChild({ button }) {return <div>{button}</div>}
Now:
Great for:
Avoid overusing it — apply when it improves clarity.