React is cool.
Actually all frameworks are cool.
They handle the tedious work of coding and allow developers to focus on optimizing workflows and logic, and deliver better code, even faster. However, along with these benefits come new anti-patterns and pitfalls.
Today I will discuss Prop Drilling in React and why it should be avoided.
What is Prop Drilling
Prop drilling is what developers refer to the practice of passing props down through multiple levels of components to reach a deeply nested child component.
Wait. Isn't passing props down to components the correct usage of React?
Correct, however it becomes an anti-pattern when the props are carried down to very deeply nested components simply because of the component structure.
Code Example
// Top-level component
const App = () => {
const user = { name: 'John Doe', age: 30 };
return <Parent user={user} />;
};
const Parent = ({ user }) => {
return <Child user={user} />;
};
const Child = ({ user }) => {
return <Grandchild user={user} />;
};
const Grandchild = ({ user }) => {
return <h1>{`Hello, ${user.name}!`}</h1>;
};
export default App;
Why is this a problem?
Complexity and Reusability
In this basic example, because we are passing down the user
prop through the intermediate components (Parent
, Child
), these components must now explicitly declare and pass down the user
prop. This causes them to loose the inherent benefit of React that allows components to be reusable.
Tight Coupling
Additionally, this practice makes components dependent on props that they don't actually use. This is especially apparent when making changes to a prop, the cascading changes inside of each intermediate component causes these updates to be time-consuming.
Mistakes Happen
Yes, we all make them sometimes...
As changes to the props requires updating multiple levels of components, this increase the chances of introducing errors into the codebase.
Alternatives
Restructuring Component Tree - Composition vs Inheritance
Prop drilling can occur when using the inheritance technique which allows each component to inherit, duplicate and extend the higher component's props. However, composition allows us to write our components to simply pass down their children without knowing them ahead of time. This eliminates the need to specify the props for each intermediate component.
const App = () => {
const user = { name: 'John Doe', age: 30 };
return (
<Parent>;
<Child>;
<Grandchild user={user} />;
</Child>;
</Parent>;
)
};
export default App;
const Parent => (props) {
return (
<div className={'parent'}>
{props.children}
</div>
)
};
Context API
Another solution to avoid this anti-pattern is to use the Context API and useContext hook to wrap components that need access to a shared piece of data. However, context in React should ideally only be used for application-wide data, not simply to avoid prop drilling.
Hopefully, this post helped you understand the issues with prop drilling and gave you a better understanding of proper component structuring in React.
You can find even more details in the React documentation.
Top comments (0)