I'm making a course on Laravel Sanctum: MasteringAuth.com

Vue 3: ref and reactive

Constantin Druc ยท 15 Jan, 2022

[00:00] There are two ways we can create reactive properties in Vue 3. One is by using the ref method, the other is by using reactive. The question is... uhm, but why? Let's start with ref. I'll create like a price property, and the way ref works, is you pass it a parameter; 100 for example, and then whenever you need the current value of the reactive property, you need to type in the name of the object, so price, and then dot value.

[00:33] But why is that? Why do we need this .value? Why can't we just type in price? To answer that we first need to understand, at least at a very high level, how reactivity works in Vue 3. The way it works is by intercepting an object's get and set methods. Whenever a property is changed on that object, Vue knows and notifies the appropriate listeners. So objects are the key component. Without them there is no reactivity. That's why the ref method creates an object and you need to type in value.

[01:05] To give you a more concrete example, let's create a ref class. This class will have a constructor that will receive value as a parameter, and then assign the value to an underscore value. The reason we're using underscore value here is to avoid conflicts with the next method, which will be get value. As soon as we attempt to grab the value, we want to add this object to our tracking list so to speak. But to keep things simple, I'll just console log; I'll say console.log("hey track this") and then return this underscore value.

[01:52] Next up, when the user of this class attempts to set a new value, the set value method is called; which will receive value as a parameter. Here we can also add a console.log and say "hey this changed", and set the value; this._value = value. Now if we were to create a ref function, we'd do something like this: function ref, receive a value, and then return new ref, and pass the value. And then to use it, we'll do const name = ref("tallpad");. If we look inside the console, nothing happened; but as soon as I type in name.value and save. That call is intercepted and our object is theoretically added to the tracking list. Then once I set a new value, so if I do name.value = "Constantin", and save, we'll see that we'll have a tracking log, and then "hey this change constantine", and this is pretty much how it works. Of course, this is a silly example; there are a lot of other things happening in the actual implementation of vue.js, but that's the gist of it.

[03:21] The most important thing to remember is that vue reactivity works by intercepting object method calls similar to what I did here, or by using a proxy. Okay, let's delete this and go back to our ref vs reactive situation. Apart from having to type in .value everywhere, creating reactive properties using ref has two significant advantages: the first one is, unlike reactive, ref works with any data type, including objects.

[03:54] The second major advantage, and this is very useful, is that if you're passing it an object, you can completely replace it with another one; this is not possible with reactive. For example, I could have an initial address and this will have street, number, and postcode. And then let's say I have an address, which is a reactive property created using ref, I could do ref, let's import it, and then pass it an object, and destructure initial address.

[04:34] Now at some point, I might want to reset the address. With ref I can just do address.value = {...initialAddress}. With reactive though, you cannot do this; it doesn't work. Ok, so you might wonder "if ref is that good, why does reactive even exist?" Well, you can look at reactive as the spiritual successor of Vue 2 data object. You can put everything in one place, into a single object, and use it without having to type in dot value every time. The resulting code usually ends up looking more aesthetically pleasing but, yeah, reactive exists just so you don't have to type in dot value.

[05:17] If you ask me, I prefer ref. I don't particularly like the value thing, but I love that it works with every data type and the fact that when I use it with objects I can replace the entire thing. But then again that's just my personal preference; you can very well use reactive. Nobody really cares.