DEV Community

Cover image for What is props reactivity loss in Vue and how to avoid it?
Jakub Andrzejewski
Jakub Andrzejewski

Posted on

What is props reactivity loss in Vue and how to avoid it?

Hey folks!

Today, I would like to share with you a problem I encountered recently in my project and how I overcome it. I will get to the point to explain the problem quicky, what are the possible solutions to solve and what we decided to go with and why - without unnecessary content polution but certain Intelligence ;)

Let me know your thoughts!

Disclaimer

I wasn't writing for some time as I needed to rethink what I want to share with you and in what form.

Basically, all my recent posts/articles were somehow AI created - either fully or highly assisted. And honestly, I don't feel ok with that. I believe what made you stay with my blog is the feeling that the author is authentic - that the problems I am solving are real and based on the everyday work with the framework I love - Vue.

So, I am changing a form. I will publish hand written (obviously not perfect) articles that will cover problems or real life case studies I have encountered a week before - no more AI generated content I promise ;)

What I believe made you stay with my blog is authenticity - I was writing about problems I was encountering everyday as I was not able to find an answer for it. This form I would like to continue - and I hope you will like it! :)

Problem

One of the developers came back to me recently saying: I have created a new feature package/module for our project (that is independent from other domains) and I encountered this problem while following the previously agreed approach:

Destructuring the `props` will cause the value to lose reactivity.
Enter fullscreen mode Exit fullscreen mode

The code was looking more or less like following:

<script setup lang="ts">
const props = defineProps<{
  apiClient: Client
}>()

const result = getProduct(apiClient, key)
// Destructuring the `props` will cause the value to lose reactivity.
</script>
Enter fullscreen mode Exit fullscreen mode

And he then asked: What should I do?

Solutions

We have considered three available solutions:

  • Use the toValue helper from Vue - this was good as temporary solution to hide the eslint error but we didn't want to go with this approach as our final option
  • The second option was to wrap the prop inside a computed property or watcher like:
    watch(() => props.apiClient, () => {
      console.log(props.apiClient)
    })
Enter fullscreen mode Exit fullscreen mode

But we didn't like this solution either as we basically were assuming that the apiClient can change - while in our case the apiClient is a static dependency.

  • Pass the apiClient via provide/inject instead. This pattern can be used to provide both reactive and static values to your app.

Selected approach

We have selected the third option as it looked the best from the architectural point of view. We have a static apiClient that we want to provide to all consumers in our app that can inject them just in the moment they need it. This also helps with the concept of prop drilling as we don't need to pass the prop in a nested tree.

But it also comes with some drawbacks such as less visible interface of individual packages externally that we wanted to achieve in the first place.

You have a better approach? Something I missed? Share it in the comments! :)

Top comments (0)