Telerik blogs
VueT2 Light_1200x303

What is nextTick in Vue.js and how can it help large code bases?

One of the common questions people ask me when they start learning Vue is: What does Vue.nextTick do? Will I need to use it in my projects? πŸ€”

What do I answer to them? πŸ€“ Yes, of course! I use it regularly on bigger code bases, which has helped me solve a few problems more than once.

☝🏼 But, as with every Vue functionality, it is essential to understand what it does precisely to know when you should rely on it (and when you should not). 🀦🏻‍♀️ I have seen a few strange scenarios where people used it a lot, bringing a lot of complexity to the app while they should have taken a step back and thought more about the architecture of what they wanted to accomplish.

😁 So that’s why I am writing this article.

But first, let’s talk about the common point of every component: its lifecycle.

The Component Lifecycle

You are probably familiar with the different steps a component goes through βš™οΈ, but a quick reminder should help a few developers among us.

Vue Lifecycle shows the steps listed here in a diagram

  • At beforeCreate() is when the lifecycle is initialized. 🎬 It is called before the Vue engine creates the component, and nothing (events, data, properties, etc.) is set up yet.

  • created() runs before the DOM is rendered. At this stage, data and events are accessible.

  • beforeMount() is where the template and scoped styles are compiled, although you still can’t manipulate the DOM, and the vm.$el instance has not been created yet.

  • When we reach mounted(), you can use and manipulate your components any way you want. πŸ’― This means your component belongs to the DOM.

  • beforeUpdate() is handy for implementing logic βš™οΈ before a change is made to your component.

  • updated() allows you to implement any logic as soon as a change is made to the component. πŸ’¨

  • Use beforeUnmount() (that replaced beforeDestroy()) to clean up your component 🧹 so you don’t leave any variables or events that could cause memory leaks to your app 😢‍🌫️.

  • unmounted() (replaces destroyed()) and can be used to clear intervals or scripts after your component is destroyed πŸ’₯.

🧐 Now let’s see where our nextTick() hook falls.

First, What Is Vue.js nextTick?

➑️ According to Vue.js official documentation, nextTick() is a utility for waiting for the next DOM update flush. This function takes a callback that will be run once the components’ update is complete. 🏁 (This update happens when you modify a data property or a computed is changed.)

export default {
  mounted() {
    this.$nextTick(() => {
      console.log(
        "I will be displayed once the next DOM update cycle is complete."
      );
    });
  },
};

⚠️ An important thing to remember is that Vue asynchronously updates the DOM (so no matter how many state changes are applied to components during an update, all of them will proceed simultaneously! ☝🏼). Only then, each nextTick() callback is called.

These callbacks can be handy when you want to execute something while ensuring that the props, the data or the computed of a children component are updated. ⏲ Your code is delayed after the next DOM update cycle is run and after the browser renders that change.

In other words, the callback is deferred to be executed after the next DOM update cycle.

Why Use Vue.js nextTick When We Can Use settimeout?

As mentioned earlier, Vue asynchronously updates the DOM. πŸ‘‰πŸΌ So when you make a change to the DOM, it doesn’t happen right away. πŸ•΅πŸ» It kind of checks first that there aren’t any other state changes. ONLY THEN do you see your changes rendered on your browser! 🎨

All this happens so fast you don’t even see it. πŸ‘€ So, why does it matter?

πŸ‘©πŸ»‍🏫 It does matter because, let’s say, you need to run a function right after that change was made. This is where you need to use nextTick() to wait for the DOM update.

This is for sure why at some point you had to use setTimeout() (am I wrong? πŸ˜‰) because you had to give some time to the browser to update the DOM. Otherwise, your function wasn’t executed. 🀷🏻‍♀️

☒️ But setTimeout() has its fallback. It will execute the callback just after the next tick (the DOM update), while nextTick() prioritizes the callback function execution! ⏱ setTimeout() delays your callback, as it first has to give the browser control by using it and only then back to you when its calls your callback function.

Let’s take an example here:

<template>
  <h1>{{ message }}</h1>
</template>

<script>
  export default {
    data() {
      return {
        message: "Joey doesn’t share food!",
      };
    },
    mounted() {
      console.log(this.message);
      this.message =
        "Well, maybe I don't need your money. Wait, wait, I said maybe!";
      console.log(this.message);
      setTimeout(() => {
        this.message = "Hi, I’m Chandler. I make jokes when I’m uncomfortable.";
      console.log(this.message);
      }, 300);
      this.$nextTick(() => {
        this.message =
          "It's a moo point. It's like a cow's opinion; it doesn't matter. It's moo.";
        console.log(this.message);
      });
    },
  };
</script>

setTimout versus nextTick - in the preview we see the 'moo point' quote for a flash before the 'Chandler, I make jokes when I'm uncomfortable' quote displays. On the right, in the Vue repl we see that all quotes processed.

πŸ‘ As you can see, nextTick() is executed before setTimeout(). This is why using nextTick() will be more performant as it will be run faster!

However, ☝🏼 it’s good to know that as a last resort on browsers that don’t support nextTick(), Promise and MutationObserver, it falls to setImmediate() on IE 6-10 and to setTimeout() for Opera Mini.

WHAT? πŸ‘‚πŸΌ I hear you whispering: Why not use watch() to listen for changes? The short answer is that watch() is used to execute something when the component data changes, while nextTick() is used to perform code after the app is updated.

Ways To Use Vue.js nextTick

There are two ways to use Vue.js nextTick: πŸ› 

πŸ‘‰πŸΌ The most common way is to pass a callback function as a first argument. πŸ‘ We’ve seen this structure in our earlier example above.

With a Callback Function

mounted () {
  this.$nextTick(() => {
    this.message = 'Call me maybe!';
    console.log(this.message);
  });
}

πŸ‘‰πŸΌ Or await the returned promise you would need if you run into an Uncaught (in promise) DOMException error. ❌

In a Regular Promise:

mounted () {
  this.$nextTick().then(() => {
    this.message = 'You promised!';
    console.log(this.message);
  });
}

With Async/Await:

async mounted () {
  await this.$nextTick(() => {
    this.message = 'I will always wait for you!';
    console.log(this.message)
  });
}

Conclusion

Indeed, in small code bases, we seldom need nextTick(). However, it still has significant advantages, especially if you happen to make API calls πŸ€™πŸΌ and need to run some logic 🧠 after receiving data from the background.

On the other hand, πŸ€“ it is vital to think about the logic of your app. If you use $nextTick way too often, 🀭 you might complexify the codebase of your app.

Let me know if I was (or wasn’t 😜) able to solve the nextTick() mystery for you. 😊 You can reach me on Twitter 🐦 @RifkiNada, or come and check my work and articles on πŸ–₯ www.nadarifki.com.

Bye, coders! πŸ‘‹πŸΌ


Vue
author-photo_nada-rifki
About the Author

Nada Rifki

Nada is a JavaScript developer who likes to play with UI components to create interfaces with great UX. She specializes in Vue/Nuxt, and loves sharing anything and everything that could help her fellow frontend web developers. Nada also dabbles in digital marketing, dance and Chinese. You can reach her on Twitter @RifkiNadaor come on her website, nadarifki.com.

Related Posts

Comments

Comments are disabled in preview mode.