Web/JavaScript

[Svelte] Lifecycle

llHoYall 2021. 11. 12. 20:17

Svelte has four lifecycle functions.

  • onMount
  • onDestroy
  • beforeUpdate
  • afterUpdate

Let's figure out them.

Create Project

Create svelte project.

I added a component for a test.

<!-- Test.svelte -->
<div>Test Component</div>

And, I added this component into index.svelte.

<!-- index.svelte -->
<script lang="ts">
  import Test from './Test.svelte';
  let toggleTest: boolean = false;
</script>

<button
  on:click={() => {
    toggleTest = !toggleTest;
  }}
>
  Toggle
</button>

{#if toggleTest}
  <Test />
{/if}

The test component will be toggled when we click the Toggle button.

onMount

onMount() lifecycle is called after a component is mounted on DOM.

onMount(callback: () => void)

We can give a callback function, and it will be called when the component is mounted.

<!-- Test.svelte -->
<script lang="ts">
  import { onMount } from 'svelte';

  onMount(() => console.log('onMount is called'));
</script>

You can check this lifecycle working via console log.

 

onMount() lifecycle can return a function, and it is called when the component is unmounted.

onMount(() => {
  console.log('onMount is called');
  return () => {
    console.log('onMount returns');
  };
});

In the past, we had to use this way because onDestroy() lifecycle didn't exist.

But, this way has some problems like asynchronous function.

In addition, this way has lesser readability than onDestroy() lifecycle.

So, I recommend you to use onDestroy() lifecycle.

onDestroy

onDestroy() lifecycle is called before a component is unmounted from DOM.

onDestroy(callback: () => void)

Let's add this lifecycle to our project.

<!-- Test.svelte -->
<script lang="ts">
  import { onMount, onDestroy } from 'svelte';

  onMount(() => console.log('onMount is called'));
  onDestroy(() => console.log('onDestroy is called'));
</script>

Test it!

beforeUpdate / afterUpdate

beforeUpdate() lifecycle is called before a component is updated, and afterUpdate() lifecycle is called after a component is updated.

beforeUpdate(callback: () -> void)
afterUpdate(callback: () -> void)
<!-- Test.svelte -->
<script lang="ts">
  import { onMount, onDestroy, beforeUpdate, afterUpdate } from 'svelte';

  onMount(() => console.log('onMount is called'));
  beforeUpdate(() => console.log('beforeUpdate is called'));
  afterUpdate(() => console.log('afterUpdate is called'));
  onDestroy(() => console.log('onDestroy is called'));
</script>

Let's add some codes to update this component.

<!-- Test.svelte -->
<script lang="ts">
  import { onMount, onDestroy, beforeUpdate, afterUpdate } from 'svelte';

  let text: string = 'Test String';

  const addDot = () => (text += '.');

  onMount(() => console.log('onMount is called'));
  beforeUpdate(() => console.log('beforeUpdate is called'));
  afterUpdate(() => console.log('afterUpdate is called'));
  onDestroy(() => console.log('onDestroy is called'));
</script>

<div>Test Component</div>
<div on:click={addDot}>{text}</div>

I added one more <div> tag and connected a function to add a dot character to the element's content.

I mounted the Test component, and click the new <div> tag twice.

It works as we thought.

tick

Svelte has one more special lifecycle named tick.

You can call this function anytime when you want, unlike other lifecycles.

tick() function returns Promise. This Promise is resolved after the DOM is updated if there are any updated things.

<!-- Test.svelte -->
<script lang="ts">
  import { onMount, beforeUpdate, tick } from 'svelte';

  let span: HTMLSpanElement;

  onMount(() => {
    console.log('onMount is called');
    span = document.querySelector('span');
  });
  beforeUpdate(async () => {
    console.log('beforeUpdate is called');
    await tick();
    span.innerText = 'Hello';
  });
</script>

<div>Test Component</div>
<span />

Try to remove the tick() function.

Then, you will see the error, because the <span> tag doesn't exist when the component isn't mounted yet.

tick() function asynchronously wait until the component is updated.

Closing Remarks

In this posting, we took a look at the four lifecycles of Svelte.

In addition, we took a look at the tick() lifecycle as well.

This function is very important in developing using Svelte.

So, please fully understand it.