CARVIEW |
What is prop drilling in React?
Prop drilling in React
React developers often encounter scenarios where they must pass data/state from a top-level component to a deeply nested component. Prop drilling refers to transporting this data/state as props to the intended destination through intermediate components.
Example
Consider a visual representation of the component tree for a simple furniture e-commerce site to understand the problem better:
Suppose the top-level App
Component has access to the state of our shopping cart; we want to update the state by changing the button color from green to grey whenever the user clicks the "Add to Cart"
button.
Let's implement the scenario above to understand it. Run the code and try clicking the "Add to Cart"
button.
import React from 'react'; require('./styles.css'); import ReactDOM from 'react-dom'; import App from './App.js'; ReactDOM.render( <App />, document.getElementById('root') );
Explanation
Lines 6-14: We set the state of the shopping cart and define a method
changeColor
that is responsible for changing state.Line 23: We pass
buttonColor
andchangeColor
as props toProductCard
component.Line 38: The
ProductCard
component then passes the props it received to theButton
component.Line 50: The
Button
component passeschangeColor
props to theonClick
event. The event fires when the button is clicked and sets the state of button to color grey.Line 51: The button element reflects the change in state by turning the
backgroundColor
attribute from green to grey to signal that product has been added to cart.
Issue
As can be observed from the code in the example app above, this approach is redundant and cumbersome even in a simple app. We pass state/data manually through components that don't require it, making our code cluttered and difficult to maintain. In addition, we may accidentally rename props midway through this 'drilling' process and run into bugs. These issues are compounded for large-scale applications, thus making this process infeasible.
Solution
There are three alternative solutions to solve the problem we encountered above:
Redux: An external library that offers state management for React applications.
Context: An API that enables sharing inherently global data/state with components at different nesting levels.
Component composition: A technique which involves passing components to other components as props. It has two subcategories:
Container components
Specialized components
For our example above, using Redux would needlessly involve an external library, and the Context API would pose issues with reusability and performance when the application is scaled up. Hence, component composition is a viable solution. The other two solutions may cater to different use cases involving prop drilling.
Code
The app below shows modified code that uses composition with container components:
import React from 'react'; require('./styles.css'); import ReactDOM from 'react-dom'; import App from './App.js'; ReactDOM.render( <App />, document.getElementById('root') );
Explanation
Lines 17–24: We put our code structure directly in the top-level component:
App
, which enables us to pass required props directly toButton
component.Line 33: We use the default
to render thechildren prop https://legacy.reactjs.org/docs/composition-vs-inheritance.html Details
andButton
components withinProductCard
.
Conclusion
There are different ways to solve the issue of prop drilling. This article focused on component composition as a solution due to its effectiveness and simplicity for most use cases.
Relevant Answers
Explore Courses
Free Resources