The one rule for calling lifecycle functions
The only rule for calling component lifecycle functions is that you should call them during component initialization. If no component is being initialized, Svelte will complain by throwing an error.
Let’s look at the following example:
<script> import { onMount } from 'svelte'; function buttonClicked() { onMount(() => console.log('onMount!')); } </script> <button on:click={buttonClicked} />
When you click on the button, it will call buttonClicked
, which will call onMount
. As no component is being initialized when onMount
is being called, (the component above has initialized and mounted by the time you click on the button), Svelte throws an error:
Error: Function called outside component initialization
Yes, Svelte does not allow lifecycle functions to be called outside of the component initialization phase. This rule dictates when you can call the lifecycle functions. What it does not dictate is where or how you call the lifecycle functions. This allows us to refactor lifecycle functions and call them in other ways.
Refactoring lifecycle functions
If you look carefully at the rule for calling lifecycle functions, you will notice that it is about when you call them, and not where you call them.
It is not necessary to call lifecycle functions at the top level within the <
script>
tag.
In the following example, the setup
function is called during component initialization, and in turn calls the onMount
function:
<script> import { onMount } from 'svelte'; setup(); function setup() { onMount(() => console.log('onMount!')); } </script>
Since the component is still initializing, this is perfectly fine.
It is also not necessary to import the onMount
function within the component. As you see in the following example, you can import it in another file; as long as the onMount
function is called during component initialization, it is perfectly fine:
// file-a.js import { onMount } from 'svelte'; export function setup() { onMount(() => console.log('onMount!')); }
In the preceding code snippet, we’ve moved the setup
function we defined previously to a new module called file-a.js
. Then, in the original Svelte component, rather than defining the setup
function, we import it from file-a.js
, shown in the following code snippet:
<script> import { setup } from './file-a.js'; setup(); </script>
Since the setup
function calls the onMount
function, the same rule applies to the setup
function too! You can no longer call the setup
function outside component initialization.
Which component to register?
Looking at just the setup
function, you may be wondering, when you call the onMount
function, how does Svelte know which component’s lifecycle you are referring to?
Internally, Svelte keeps track of which component is initializing. When you call the lifecycle functions, it will register your function to the lifecycle of the component that is being initialized.
So, the same setup
function can be called within different components and registers the onMount
function for different components.
This unlocks the first pattern in this chapter: reusing lifecycle functions.