Let's avoid "Props Drilling"

Let's avoid "Props Drilling"

Sathya Molagoda's photo
Sathya Molagoda
·May 24, 2022·

4 min read

Play this article

Table of contents

  • Usage and Implementation of Props
  • Why Provide/Inject?
  • Conclusion

Here I am going to discuss two fundamental pieces of Vuejs that I believe having better knowledge about them will be helpful for your work. Whether you are a pro, amateur, or beginner, I will explain these two concepts in a simple way to make them understand easier. In front-end development, we have passed data ​​from parent components to child components in many ways. In Vuejs, we commonly use Props. But in more complex scenarios like components tree, we use Provide/Inject to pass data from ancestor component to deep child. Most amateur Vuejs developers often make a mistake. That is passing data from an ancestor component to a deep child in the component tree using props. All the in-between components have to keep the props unnecessarily, whether they are needed or not. This is called "Props Drilling", and it's not something fun to deal with. After reading this article, you will never make that mistake again.

Usage and Implementation of Props

First, get to know about props. We can declare props in two ways. The below example will explain it.

<template>
  <div>
    <button v-if="isVisible" type="submit">{{ buttonText }}</button>
  </div>
</template>

Declare props as String array,

<script>
export default {
  props: ['buttonText', 'isVisible'],
}
</script>

Declare props as an Object,

<script>
export default {
  props: {
    buttonText: String,
    isVisible: Boolean,
  },
}
</script>

When declaring props as an object, the key will be the prop name, and the value will be the constructor function of the expected type.

prop object.png

Props are more suitable when passing data to a child component from the parent component (If the component hierarchy is limited to two levels). If the data passes beyond the first child to a deep child in the component tree, we must use the provider/inject method instead of props to avoid props drilling. Let's discuss the reason for that under the next subtopic.

Why Provide/Inject?

Refer to the below image carefully,

component tree.png

In the above image main component holds username data. And component A, component D, and component F use the username to show user information. Passing a prop to component A is not an issue as there is no intermediate component between A and Main components. But if we check Component D, we have Component B as an intermediate component between the Main Component and Component D. This scenario is somewhat similar to Component F. Component C and Component E stay as intermediate components between Main Component and Component F. All these intermediate components hold username prop unnecessarily without any usage. Think, if the component is to be nested 5 to 20 levels deep, all the in-between components have to hold the prop to forward data to the deep child component. Imagine data like authenticated user details and language preferences which are used everywhere in the applications. Plenty of components might use that data to handle different functionality across the application. In such a scenario, it’s better to access those data directly from those components. There comes the Provide/Inject. Let’s check the below image.

provide.png

We can implement Provide as below. We have to Provide data from the Main Component which is needed for deep child components. The parent component serves as a dependency provider to its descendants.

<script>
export default {
  data() {
    return {
      preferedLanguage: 'en',
      userDetails: {
        username: 'testUser',
        firstName: 'Sathya',
        lastName: 'Molagoda',
        isActive: true,
      },
    }
  },
  provide() {
    return {
      language: this.preferedLanguage,
      username: this.username,
    }
  },
  computed: {
    username() {
      return this.userDetails.username 
    }
  },
}
</script>

From the child component, we can Inject as below,

<script>
export default{
  inject:['username']
}
</script>

In this way, all the child components can inject provided data from Main Component.

Conclusion

There is no hard and fast rule for using dependency injection in Vuejs, even if you are passing props for a component that is deep in the hierarchy. But having props drilling is not a fun thing in the project. So we can use Provide/Inject to increase the quality of the code and the application. Now we all know where we should use Props and where we should use Provide and Inject. For more information, you can refer to the below links:

· Vuejs

· Props

· Provide/Inject

Comment your thoughts and ideas below, and let me know what topics you like to discuss on this forum.

 
Share this