Skip to main content

Méthodes de cycle de vie

En Svelte 5, le cycle de vie d’un composant n’est constitué que de deux parties : sa création et sa destruction. Tout ce qui est entre les deux — les mises à jour des états — n’est pas directement lié au composant en tant que tel ; seuls les morceaux qui ont besoin de réagir aux changements d’état sont notifiés. Cela s’explique par le fait que sous le capot, la plus petite unité de changement n’est pas le composant, mais les effets (de rendu) qu’un composant définit lors de son initialisation. En conséquence, il n’existe pas de méthode permettant d’accéder à l’"avant mise à jour”/"après mise à jour” (before update, after update).

onMount

La fonction onMount définit un callback à exécuter dès que le composant est monté dans le DOM. onMount doit être exécutée lors de l’initialisation du composant (mais n’a pas besoin d’être exécutée au sein du composant ; elle peut être appelée depuis un module extérieur).

onMount n’est pas exécutée lors du rendu serveur d’un composant.

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

	onMount(() => {
		console.log('le composant a été monté');
	});
</script>

Si une fonction est renvoyée par onMount, elle sera appelée lorsque le composant sera démonté.

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

	onMount(() => {
		const interval = setInterval(() => {
			console.log('bip');
		}, 1000);

		return () => clearInterval(interval);
	});
</script>

Ce comportement ne fonctionne que si la fonction passée à onMount renvoie une valeur de manière synchrone. Les fonctions async renvoient toujours une Promise, et en tant que telles ne peuvent pas renvoyer une fonction de manière synchrone.

onDestroy

Définit un callback à exécuter juste avant que le composant ne soit détruit.

Parmi onMount, beforeUpdate, afterUpdate et onDestroy, c’est la seule de ces méthodes à être exécutée lors du rendu côté serveur.

function onDestroy(fn: () => any): void;
<script>
	import { onDestroy } from 'svelte';

	onDestroy(() => {
		console.log('le composant va être détruit');
	});
</script>

tick

Même s’il n’y a pas de méthode “après mise à jour”, vous pouvez tout de même utiliser tick pour vous assurez que l’interface est mise à jour avant de continuer. tick renvoie une Promise qui est résolue lorsque tous les mises à jour en attente ont été traitées, ou lors que la prochaine micro-tâche si aucune mise à jour n’est prévue.

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

	$effect.pre(() => {
		console.log('le composant va se mettre à jour');
		tick().then(() => {
				console.log('le composant vient de se mettre à jour');
		});
	});
</script>

Dépréciés: beforeUpdate / afterUpdate

Svelte 4 possédaient des méthodes qui étaient exécutées avant ou après que le composant en entier soit mis à jour. Pour des raisons de rétro-compatibilité, ces méthodes ont été adaptées à Svelte 5, mais ne sont pas disponibles dans les composants qui utilisent les runes.

<script>
	import { beforeUpdate, afterUpdate } from 'svelte';

	beforeUpdate(() => {
		console.log('le composant va se mettre à jour');
	});

	afterUpdate(() => {
		console.log('le composant vient de se mettre à jour');
	});
</script>

Utilisez $effect.pre à la place de beforeUpdate et $effect à la place de afterUpdate — ces runes offrent un contrôle plus granulaire et réagissent uniquement aux changements qui les intéressent.

Exemple d’une fenêtre de chat

Pour implémenter une fenêtre de chat qui défile automatiquement vers le bas lorsque de nouveaux messages sont reçus (mais uniquement si vous étiez déjà en bas de la fenêtre), nous avons besoin de mesurer le DOM avant de le mettre à jour.

En Svelte 4, nous faisons cela avec beforeUpdate, mais cette approche est imparfaite — elle s’exécute avant chaque mise à jour, qu’elle soit pertinente ou non. Dans l’exemple ci-dessous, nous avons besoin d’ajouter des vérifications comme updatingMessages pour nous assurer que nous ne touchons pas à la position du défilement lorsque le mode sombre est activé ou désactivé.

Avec les rune, nous pouvons utiliser $effect.pre, qui fonctionne comme $effect mais est exécuté avant la mise à jour du DOM. Tant que la variable messages est explicitement référencée dans le corps de l’effet, cet effet sera ré-exécutée lorsque la variable messages est mise à jour, mais pas lorsque la variable theme change.

beforeUpdate, et sa tout aussi problématique contrepartie afterUpdate, sont donc dépréciées par Svelte 5.

<script>
	import { beforeUpdate, afterUpdate, tick } from 'svelte';

	let updatingMessages = false;
	let theme = $state('dark');
	let messages = $state([]);

	let viewport;

	beforeUpdate(() => {
	$effect.pre(() => {
		if (!updatingMessages) return;
		messages;
		const autoscroll = viewport && viewport.offsetHeight + viewport.scrollTop > viewport.scrollHeight - 50;

		if (autoscroll) {
			tick().then(() => {
				viewport.scrollTo(0, viewport.scrollHeight);
			});
		}

		updatingMessages = false;
	});

	function handleKeydown(event) {
		if (event.key === 'Enter') {
			const text = event.target.value;
			if (!text) return;

			updatingMessages = true;
			messages = [...messages, text];
			event.target.value = '';
		}
	}

	function toggle() {
		toggleValue = !toggleValue;
	}
</script>

<div class:dark={theme === 'dark'}>
	<div bind:this={viewport}>
		{#each messages as message}
			<p>{message}</p>
		{/each}
	</div>

	<input onkeydown={handleKeydown} />

	<button onclick={toggle}> Activer / Désactiver le mode sombre </button>
</div>

Modifier cette page sur Github