Education

React State Management Solutions for Prop Drilling

logo

DhiWise

October 4, 2022
image
Author
logo

DhiWise

{
October 4, 2022
}

While building React application developers are often required to pass the data/state from the top-level component to the deeply nested components and it is done using props. However, if we have multiple numbers of intermediate components then every child must accept the data and pass it to its child component which ultimately leads to the terrible issue called prop drilling. 

To solve this issue, React provides multiple state management solutions that allow you to pass the data through the component tree without having to manually pass props down, every time you need to update the state. 

In this post, we will explore more about the prop drilling issue in React, and the different state management solutions for handling it in the React applications. 

So let's get started!

What is prop drilling and is there any state management solution?

Let's take a simple scenario in the eCommerce web application. A top-level component in the app wants to access the state of the shopping cart on the button click event. Here we want to update the state by changing the button color from pink to gray when the user clicks the “Add to Cart”  button.

Code implementation for the above scenario:

import React from "react";
 
export default class App extends React.Component{
 constructor() {
   super()
   this.state = {
     buttonColor: "#FF69B4"
   }
   this.changeColor = this.changeColor.bind(this)
 }
 
 changeColor() {
   this.setState({ buttonColor: "grey" })
 }
 
 render() {
   return (
   
   <div>
 
     {/* ProductCard component require to accept
       extra props to send them to the Button component */}
      <ProductCard buttonColor={this.state.buttonColor} changeColor={this.changeColor} 	/>
     </div>
     
   );
 }
}

class ProductCard extends React.Component {
 render() {
   return (
   
   <div className="product-card">
   <Details item="Men Blue Classic Tartan Checks Checked Casual Shirt" price="$50" />
 
     {/* The props are passed further
       Down to the next level to the Button component  */}
        <Button buttonColor={this.props.buttonColor} changeColor={this.props.changeColor} 	/>
     </div>
     
   );
 }
}

class Button extends React.Component {
 render() {
   return (
   
   <button className="button small-button w-button" onClick={this.props.changeColor} style={{ backgroundColor: this.props.buttonColor }}>
Add to Cart
</button>

   );
 }
}

class Details extends React.Component {
 render() {
   return (
   
<div className="details">
<div className="product-title">
<h2>{this.props.item}</h2>
<span>{this.props.item}</span>
</div>
<p className="product-description">Blue tartan checks checked opaque Casual shirt ,has a spread collar, button placket, short regular sleeves, curved hem</p>
</div>
   );
 }
}

Code Explanation: 

In the code above you can see that the state of the shopping cart is set  and the method changeColor is defined to change the state.  Next in the code, we passed the props buttonColor and changeColor to the ProductCard component. 

ProductCard component passes the props to the Button component which then passes it to the onClick event in the next level down the tree. 

Finally, the event is triggered when the button is clicked, it sets the state of the button from pink to gray color by changing the background color attribute as shown below.

Output:

men-blue

So what have you observed in the above example? 

To change the state of the component down in the tree you need to pass the state/data manually through all the intermediate levels that actually don't require it. This makes the code lengthy and difficult to maintain. 

Additionally, there are more chances of errors such as

  1.  Accidentally renaming the props halfway. 
  2. Refactor the shape of some data.
  3. Over-forwarding of props than necessary.
  4. Under forwarding of props and/or abusing default props.

And there are various other situations where prop drilling can bring real frustration in the maintenance and refactoring process; it may grow much more complex in large-scale projects. 

React State management solution for prop drilling?

To solve the problem of prop drilling there are three solutions:

  1. React Context API: An API that enables sharing of global data /state with the components in the app on different levels. 
  2. Redux: The library offers state management for React applications.
  3. Component Composition: A simple technique that helps you to avoid passing props through many levels. 

In the next section, we will find out when to use the React Context API, Redux, and Component composition. 

React Context API and when to use it?

React Context API provides a way to share data/states between the components without explicitly passing the prop through every layer down the tree. Context is designed to share data or state that is considered global for the tree of react components. Context lets you “broadcast” such data and updates it to all the components in the tree. 

However, using context makes component reuse more difficult. Therefore Context should only be used when some data needs to be accessed by multiple components at different nesting levels. 

In the above example, there is no deep nesting of components and the data needs to be accessed by only one component. So, let's check the other alternatives for state management.

Redux Library

Redux is the lightweight, predictable state container for JavaScript that lets developers write apps that behave consistently and support different environments i.e client, server, and native. Apps built using Redux are easy to write, understand, and test.

The library works best for both static and dynamic data in the React application and is easily extensible. However, as an external library using Redux in the app requires additional installation which may increase the final bundle size. Also, it requires extensive setup to integrate it into the app. 

Overall, using Redux for small applications isn’t a good idea. It should be used when you want to handle lots of dynamic data in a large application. 

Component Composition: 

In React, components can be made more generic by accepting props. The techniques let you pass components as props to other components and thus create components with other components. It is also helpful in reducing the number of re-renders in the application. 

According to the React docs the “Component Composition” is the simplest solution for prop drilling in small applications. It does not affect component reuse and is more efficient compared to the other two solutions for prop drilling in simple React applications.

Wrapping Up:

In the article, we have learned what is prop drilling issue in React applications and which are the different ways ( i.e using Context API, Redux, and Component Composition) we can avoid passing props through the different levels in the tree on the state change. We have also learned when to use those solutions in the React.js app.

Well, if you are a web app developer and want to simplify React.js web application development then try using DhiWise. The platform accelerates development 5x faster by eliminating repetitive tasks with its unique features.

Some of the key features of DhiWise web app builder are:

  1. Figma to code conversion
  2. UI customization support 
  3.  Integration with multiple developer tools like GitHub, GitLab, Storybook, and Vercel.
  4. Complete code ownership  
  5. Ready to use app templates 
  6. Support for team development, sharing, and collaboration
  7. And so on

Know more about the amazing platform and the supported technologies. Sign up now to quickly start your development.