The mistake I want to share with you in this video isn't so much a mistake that will cause unexpected bugs, but it'll definitely slow you down as you're developing. I can't tell you how many times I have written a watcher, run the code, and then spent like five to ten minutes trying to figure out why the callback isn't running. So what's the issue with this example code that I've prepared? It looks pretty straightforward, right?
We've declared a reactive ref numbers. Then we watch numbers for any changes and console log new number added whenever the numbers array changes. In the template, we display a button that pushes a new random number to the array whenever it's clicked. However, if I go over to my browser, click the button, and we'll do it just a few times for good measure, and then check the console, you'll notice we don't have our message logged.
At this point, you might be a little like me and are confused as to why the callback isn't running. Well, let me give you just a moment to consider the code and see if you can spot my mistake. Did you figure it out? OK, well, let me show you what the problem is.
The problem is that I'm not watching the array deeply with the deep option. Let's give that a try just to make sure this is the issue. And yeah, now we have the new number added message logged three times to the console. So why is this necessary?
Well, if we were replacing the array in its entirety, we wouldn't have to watch it deeply. However, because we are mutating an element within the array, in other words, we're adding a new item to the array, or this also could apply to removing items from an array or modifying the value of an existing item in an array. In all such cases, we must use the deep option. The only time where you don't need the deep option on arrays is when you're replacing the entirety of the array, which we could do if we modified our example like this.
Give the page a refresh. And yeah, that works just the same. However, this isn't quite as intuitive to write, and I prefer just using the deep option and pushing numbers to my arrays. Finally, what makes this a little bit more difficult to remember is that in Vue version two, we actually didn't have to do this.
But according to the Vue three migration guide, this new breaking change means that whenever we're watching an array, the callback will only trigger when the array is replaced. So if you need to trigger on a mutation, the deep option now must be specified. So there you have it. If your callbacks aren't firing as you expect, the first thing to check is, do I need the deep option?