A component lifecycle function is not new, it is available in every major framework, it is a Hook Hook function, the so-called Hook, is actually a callback, it is declared in advance, and will be called automatically when appropriate.

Each component, from creation to destruction, has lifecycle functions that allow us to perform the actions we need at key points in the lifecycle

Tips:

  1. In Svelte, lifecycle functions can only be written at component initialization to bind callbacks to component instances, and lifecycle functions cannot be placed in, for example, asynchronoussetTimeoutIn the.
  2. If you use server-side rendering (SSR), in additiononDestroyThe rest of the life cycle functions are not executed during SSR runs.

onMount

OnMount is the most common lifecycle function. It fires immediately after the component is first rendered into the DOM

<script>
  // Svelte lifecycle functions need to be introduced before they can be used
  import { onMount } from 'svelte';
  let photos = [];

  // onMount is a function that receives a callback
  // If the onMount callback returns a function, that function will be called when the component is destroyed
  onMount(async() = > {const res = await fetch(`https://jsonplaceholder.typicode.com/photos?_limit=20`);
    photos = await res.json();
  });
</script>
Copy the code

onDestroy

To do some finishing or cleaning when you destroy a component, use onDestroy.

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

  let seconds = 0;

  const interval = setInterval(() = > seconds += 1.1000);
  
  // Clear the timer
  onDestroy(() = > clearInterval(interval));
</script>

<p>
  The page has been open for
  {seconds} {seconds === 1 ? 'second' : 'seconds'}
</p>
Copy the code

While it is important to call lifecycle functions during component initialization, it does not matter where they are called from.

As long as the corresponding lifecycle function can be executed when the component is initialized

<script>
  The onDestory method is not defined in the component, but in the utility file
  import { onInterval } from './utils.js';

  let seconds = 0;
  onInterval(() = > seconds += 1.1000);
</script>

<p>
  The page has been open for
  {seconds} {seconds === 1 ? 'second' : 'seconds'}
</p>
Copy the code

uitls.js

import { onDestroy } from 'svelte';

export function onInterval(callback, milliseconds) {
  const interval = setInterval(callback, milliseconds);

  onDestroy(() = > clearInterval(interval));
}
Copy the code

BeforeUpdate and afterUpdate

BeforeUpdate functions are executed before DOM updates, while afterUpdate is executed after data is synchronized to the DOM

beforeUpdate(() = > {
  // Because the lifecycle function in svelte is called when the component is initialized
  // The first call is before onMount, so you need to check if div exists
	autoscroll = div && (div.offsetHeight + div.scrollTop) > (div.scrollHeight - 20);
});

afterUpdate(() = > {
	if (autoscroll) div.scrollTo(0, div.scrollHeight);
});
Copy the code

tick

In Svelte, when you update the DOM state, you don’t do it immediately, but you wait to see if any other changes need to be applied, including DOM changes on other components. And then change it for the next microtask. Doing so reduces some of the waste and allows the browser to batch these things more efficiently.

Features:

  1. The tick doesn’t have to be called at first initialization, you can call it at any time
  2. The return value is a Promise
<script>
  let bookName = 'js starter'
  let bookNode 
	
  function upperBookName() {
    bookName = bookName.toUpperCase()
		
    // DOM updates do not come immediately, but with a delay
    console.log(bookNode.textContent) // => title: JS starter
    
    // Svelte finishes updating the DOM after output
  }
</script>

<span bind:this={bookNode}>Title: {bookName}</span>
<button on:click={upperBookName}>A capital</button>
Copy the code

The solution

// When it is about to be done, place it in the timer. Since the timer is a macro task, the execution of the macro task must be after the micro task
let timer = setTimeout(() = > console.log(bookNode.textContent), 0)
Copy the code
// Put the corresponding operation in afterUpdate, and the DOM must have been updated
afterUpdate(() = > console.log(bookNode.textContent))
Copy the code
bookName = bookName.toUpperCase()

await tick() // Wait for DOM updates to complete before executing subsequent code
console.log(bookNode.textContent)
Copy the code