Expecting Changes to Non-Reactive Dependencies to Trigger Updates — Transcript

Transcript of the free Vue.js lesson Expecting Changes to Non-Reactive Dependencies to Trigger Updateswatch the video lesson.

Another common mistake I see devs make is to expect changes to non-reactive data to trigger updates in the DOM. Let me show you an example of what that might look like. In fact, I witnessed someone do this exact same thing just this week. So let's see what it looks like.

Here on line three of my code, I'm creating a computed data property. And I'm just setting its value to whatever is in local storage for this data key. Then down inside of my template, I'm setting the initial value to that data property. On input in this event, so whenever the user types in the input, I'm calling a function updateData.

updateData simply grabs what the user typed in and then sets it back to local storage. Finally, below the input, I am printing out the value of that data. OK, so over in the browser now, if I type in the input, you might expect that the message typed into the input displays also in real time below it. However, as you can see, that's not the case.

Why not? If I open up the DevTools, and take a look in my local storage, you can see we are in fact setting things to local storage correctly. In fact, if I type in the input, the value does update in real time in local storage. But why is my computed data prop that's being printed below the input not updating along with it?

To make matters even more confusing, if I refresh my page, you'll see that we do have the message printed below the input. But going back and changing the input now at this point doesn't change the message rendered below. What is going on? Well, the key to this is that computed relies on reactive dependencies in order to know when it should update.

Local storage is not a reactive dependency. And therefore, this computed function is never rerun and the DOM is never updated. So how would we go about fixing this issue? Well, there's a couple of different solutions we could reach for.

We could reach for a third-party library like Vue Use, which would make things super simple. However, let me show you a little bit more manual approach. What I'm going to do instead, since the goal is to make computed here, rely on reactive data. Let me import ref from view because of course ref is the function we use to define reactive data.

Then I'll create a variable here called, let's just call it reactive data and I'll set it to be a ref. Now let me take local storage dot get item here. And I'll use that to set the initial value for reactive data. Great.

Now we can get rid of this computed property altogether. And instead of setting data to the value of the input and printing out data below, I'll just change that to reactive data. Perfect. Last thing we need to do is inside of update data, besides setting our data to local storage, we also need to update the reactive data prop here.

Awesome. Now over in the browser, things will work exactly as expected. The message below updates. And when I check out the dev tools, sure enough, we have the updated value there as well.

The moral of the story is this. When you're getting your data from non-reactive sources, you always will have to do a little bit more work in order to get things reacting appropriately with Vue. A lot of these reactive sources will typically be your browser native APIs. things like the local storage API, things like dates, things like network data, DOM elements, clipboard, location APIs, and more.

If you'd like to avoid some of the little bit more manual work you have to do in order to get these browser native APIs to be reactive, you can check out this amazing library called Vue Use, which is basically a wrapper around tons of browser APIs in order to make them reactive. I definitely suggest you check it out. Also, as you might expect, we do have a complete course here at Vue School teaching you all about Vue Use. So you can do things manually the way we did in this video, or you can go the easy route with Vue Use.