props-drilling

Avoid props drilling in VueJs

profile-image
Sathya Molagoda
  • August 10, 2023
  • 4 min read
Play this article

Intro

Props Drilling refers to the process of passing data from an ancestor component to a deep child in the component tree using props. In many situations, we use this technique to pass data from one container component to another, but we make an exception in the case of components deep down in tree. All the components in between these two components have to pass the prop 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. Vue provides special props argument to its components which are used to pass data from outside of the component to the component. Vue components require explicit props declaration so that Vue knows what external props passed to the component should be treated as fallthrough attributes (which will be discussed in its dedicated section). 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.

props-sample
Props Sample

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,

props-drilling-example
Props Drilling Example

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.

provider-injection-sample
Provider Injection Example

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.

Props drilling

Props

Vue.Js

NuxtJS