Understanding the Svelte lifecycle functions
When using a Svelte component, it goes through different stages throughout its lifetime: mounting, updating, and destroying. This is similar to a human being. We go through various stages in our lifetime, such as birth, growth, old age, and death, throughout our lifetime. We call the different stages lifecycles.
Before we talk about lifecycles in Svelte, let’s look at a Svelte component.
<script> import { onMount, beforeUpdate, afterUpdate, onDestroy } from 'svelte'; let count = 0; onMount(() => { console.log('onMount!'); }); beforeUpdate(() => { console.log('beforeUpdate!'); }); afterUpdate(() => { console.log('afterUpdate!'); }); onDestroy(() => { console.log('onDestroy!'); }); </script> <button on:click={() => { count ++; }}> Counter: {count} </button>
Can you tell me when each part of the code is executed?
Not every part of the code is executed at once; different parts of the code are executed at different stages of the component lifecycle.
A Svelte component has four different lifecycle stages: initializing, mounting, updating, and destroying.
Initializing the component
When you create a component, the component first goes through the initialization phase. You can think of this as the setup phase, where the component sets up its internal state.
This is where lines 2–7 are being executed.
The count
variable is declared and initialized. The onMount
, beforeUpdate
, afterUpdate
, and onDestroy
lifecycle functions are called, with callback functions passed in, to register them at the specific stages of the component lifecycles.
After the component is initialized, Svelte starts to create elements in the template, in this case, a <button>
element and text elements for "Counter: "
and {count}
.
Mounting the component
After all the elements are created, Svelte will insert them in order into the Document Object Model (DOM). This is called the mounting phase, where elements are mounted onto the DOM.
If you add Svelte actions to an element, then the actions are called with the element:
<script> function action(node) {} </script> <div use:action>
We will explore Svelte actions in more depth in Chapter 5 to 7.
If and when you add event listeners to the element, this is when Svelte will attach the event listeners to the element.
In the case of the preceding example, Svelte attaches the click
event listener onto the button after it is inserted into the DOM.
When we add bindings to an element, the bound variable gets updated with values from the element:
<script> let element; </script> <div bind:this={element} />
This is when the element
variable gets updated with the reference to the <div>
element created by Svelte.
If and when you add transitions to an element, this is when the transitions are initialized and start playing.
The following snippet is an example of adding a transition to an element. You can add a transition to an element using the transition:
, in:
, and out:
directives. We will explore more about Svelte transitions in Chapter 13 to 15:
<div in:fade />
After all the directives, use:
(actions), on:
(event listeners), bind:
bindings, in:
, transition:
(transitions), are processed, the mounting phase comes to an end by calling all the functions registered in the onMount
lifecycle functions.
This is when the function on line 4 is executed, and you will see "onMount!"
printed in the logs.
Updating the component
When you click on the button, the click
event listener is called. The function on line 9 is executed. The count
variable is incremented.
Right before Svelte modifies the DOM based on the latest value of the count
variable, the functions registered in the beforeUpdate
lifecycle function are called.
The function on line 5 is executed, and you will see the text "beforeUpdate!"
printed in the logs.
At this point, if you attempt to retrieve the text content within the button, it would still be "
Counter: 0"
.
Svelte then proceeds to modify the DOM, updating the text content of the button to "
Counter: 1"
.
After updating all the elements within the component, Svelte calls all the functions registered in the afterUpdate
lifecycle function.
The function on line 6 is executed, and you will see the text "afterUpdate!"
printed in the logs.
If you click on the button again, Svelte will go through another cycle of beforeUpdate
, and then update the DOM elements, and then afterUpdate
.
Destroying the component
A component that is conditionally shown to a user will remain while the condition holds; when the condition no longer holds, Svelte will proceed to destroy the component.
Let’s say the component in our example now enters the destroy stage.
Svelte calls all the functions registered in the onDestroy
lifecycle function. The function on line 7 is executed, and you will see the text "onDestroy!"
printed in the logs.
After that, Svelte removes the elements from the DOM.
Svelte then cleans up the directives if necessary, such as removing the event listeners and calling the destroy method from the action.
And that’s it! If you try to recreate the component again, a new cycle starts again.
The Svelte component lifecycle starts with initializing, mounting, updating, and destroying. Svelte provides lifecycle methods, allowing you to run functions at different stages of the component.
Since the component lifecycle functions are just functions exported from 'svelte'
, can you import and use them anywhere? Are there any rules or constraints when importing and using them?
Let’s find out.