DEV Community

Tan Li Hau
Tan Li Hau

Posted on • Edited on

2 amazing use case of tick() in Svelte that you must know

According to the tutorial, tick() is a function that returns a promise that resolves as soon as any pending state changes have been applied to the DOM.

But, how is this tick() function useful, why do you need tick(), and when you'll use tick()?

Here's 2 great examples of using tick() that you should't miss out on!

1. Waiting for reactive declared variables to get updated

Say you reactively declared a variable

$: double = value * 2
Enter fullscreen mode Exit fullscreen mode

updating value won't immediately update double.

👉 watch me explained why is that so on youtube:

So, here's how tick() can help. tick() returns a promise that resolves when svelte finishes the upcoming update cycle.

Meaning, by the time tick() resolves, you double is updated too!

<script>
  import { tick } from 'svelte';

  let count = 1;
  $: double = count * 2;

  async function increment() {
    count ++;
    // double is still 2

    await tick();

    // 🎉 double is now 4!
    console.log(double); // 4
  }
</script>
Enter fullscreen mode Exit fullscreen mode

2. Waiting for svelte to update the DOM elements

Say you update a variable, svelte updates the DOM asynchronously.

💡 This allow Svelte to batch DOM updates.

However, that means, if you try to read the content / attribute of the DOM element immediately, you are out of luck!

<script>
  import { tick } from 'svelte';

  let count = 1;
  let div;

  async function increment() {
    count ++;

    // div still shows '1'
    console.log(div.textContent); // '1'
  }
</script>

<div bind:this={div}>{count}</div>
Enter fullscreen mode Exit fullscreen mode

tick() comes in handy in this case.

So, await for tick(), by the time it resolves, the DOM has updated!

<script>
  import { tick } from 'svelte';

  let count = 1;
  let div;

  async function increment() {
    count ++;

    // div still shows '1'
    console.log(div.textContent); // '1'

    await tick();

    // 🎉 div now showing '2'
    console.log(div.textContent); // '2'
  }
</script>

<div bind:this={div}>{count}</div>
Enter fullscreen mode Exit fullscreen mode

📹 Watch me breaking it down in my YouTube video

Bonus

Here's a few more examples when tick() comes in handy!

Querying dynamic content created using {@html}

<script>
  import { tick } from 'svelte';

  let div;
  let dynamicContent = '<div></div>';

  async function updateContent(newContent) {
    dynamicContent = newContent;

    await tick();

    // div is now updated
    // you can query the new elements
    div.querySelector('div').forEach(doSomething);
  }
</script>

<div bind:this={div}>{@html dynamicContent}</div>
Enter fullscreen mode Exit fullscreen mode

Restoring input cursor position after updating input value

<script>
  import { tick } from 'svelte';
  let value = '';

  async function onInput(event) {
    const input = this;
    let selectionStart = input.selectionStart;
    let selectionEnd = input.selectionEnd;

    value = input.value.toUpperCase();

    await tick();

    input.selectionStart = selectionStart;
    input.selectionEnd = selectionEnd;
  }
</script>

<input on:input={onInput} {value} />
Enter fullscreen mode Exit fullscreen mode

Top comments (0)