Aller au contenu principal

Réactivité et événements Svelte

Notions théoriques

La réactivité automatique

En Svelte, toute variable déclarée avec $state() est réactive : quand sa valeur change, l'interface se met à jour automatiquement. Pas besoin d'appeler une fonction de mise à jour manuellement.

<script>
let compteur = $state(0)
</script>

<p>{compteur}</p>
<button onclick={() => compteur++}>+1</button>

Chaque clic sur le bouton incrémente compteur, et le <p> se met à jour immédiatement.

Les événements

En Svelte 5, les événements s'écrivent avec la syntaxe des attributs HTML normaux :

ÉvénementSyntaxe Svelte
Clic sur un boutononclick={maFonction}
Saisie dans un champoninput={maFonction}
Soumission d'un formulaireonsubmit={maFonction}
Survolonmouseenter={maFonction}
<script>
function saluer() {
alert('Bonjour !')
}
</script>

<button onclick={saluer}>Me saluer</button>

Ou avec une fonction fléchée inline :

<button onclick={() => alert('Bonjour !')}>Me saluer</button>

La liaison bidirectionnelle : bind:value

Pour lier un <input> à une variable réactive, Svelte propose la directive bind:value :

<script>
let prenom = $state('')
</script>

<input bind:value={prenom} placeholder="Votre prénom" />
<p>Bonjour, {prenom} !</p>

bind:value remplace le couple value={prenom} oninput={e => prenom = e.target.value} vu dans la séance précédente. C'est la syntaxe recommandée en Svelte.

Les blocs conditionnels : \

Pour afficher du contenu conditionnellement :

<script>
let connecte = $state(false)
</script>

{#if connecte}
<p>Bienvenue !</p>
{:else}
<p>Veuillez vous connecter.</p>
{/if}

<button onclick={() => connecte = !connecte}>
{connecte ? 'Se déconnecter' : 'Se connecter'}
</button>

Les boucles : \

Pour afficher une liste d'éléments :

<script>
let fruits = $state(['Pomme', 'Banane', 'Orange'])
</script>

<ul>
{#each fruits as fruit}
<li>{fruit}</li>
{/each}
</ul>

Avec l'index :

{#each fruits as fruit, index}
<li>{index + 1}. {fruit}</li>
{/each}
attention

{#each} nécessite un tableau. Si la variable est null ou undefined, Svelte génère une erreur. Initialisez toujours vos tableaux avec $state([]).

La réactivité dérivée : $derived

Pour calculer une valeur à partir d'autres variables réactives, utilisez $derived :

<script>
let prix = $state(100)
let quantite = $state(3)
let total = $derived(prix * quantite)
</script>

<p>Total : {total} €</p>

total est recalculé automatiquement chaque fois que prix ou quantite change.


Exemple pratique

Un composant de liste de tâches complet :

<script>
let taches = $state(['Apprendre Svelte', 'Créer un composant'])
let nouvelleTache = $state('')
let nombreTaches = $derived(taches.length)

function ajouterTache() {
if (nouvelleTache.trim()) {
taches = [...taches, nouvelleTache.trim()]
nouvelleTache = ''
}
}

function supprimerTache(index) {
taches = taches.filter((_, i) => i !== index)
}
</script>

<main>
<h1>Mes tâches ({nombreTaches})</h1>

<div class="saisie">
<input bind:value={nouvelleTache} placeholder="Nouvelle tâche..." />
<button onclick={ajouterTache}>Ajouter</button>
</div>

<ul>
{#each taches as tache, index}
<li>
{tache}
<button onclick={() => supprimerTache(index)}>✕</button>
</li>
{/each}
</ul>
</main>
Modification d'un tableau réactif

En Svelte 5, pour déclencher la réactivité lors de la modification d'un tableau, on remplace le tableau entier : taches = [...taches, nouvelleTache] au lieu de taches.push(nouvelleTache). La réaffectation (taches = ...) est ce qui notifie Svelte du changement.


Test de mémorisation/compréhension


Quelle directive Svelte lie bidirectionnellement un input à une variable ?


Quelle syntaxe Svelte affiche un bloc conditionnel ?


Quelle syntaxe Svelte parcourt un tableau `items` ?


Quelle rune Svelte 5 calcule une valeur dérivée d'autres variables réactives ?


Comment ajouter un élément à un tableau réactif en Svelte 5 pour déclencher la réactivité ?


Quelle est la syntaxe correcte pour gérer le clic sur un bouton en Svelte 5 ?



TP pour réfléchir et résoudre des problèmes

Dans ce TP, vous allez créer une application de liste de courses : l'utilisateur peut ajouter des articles, les cocher et les supprimer.

Étape 1 — Préparer le projet et les données

Créez un projet Vite+Svelte, puis dans src/App.svelte, déclarez la structure de données :


Bonne pratique - id unique pour chaque élément

Donnez un id unique à chaque objet d'un tableau affiché avec {#each}. Cela permet à Svelte de faire des mises à jour efficaces et évite des bugs visuels lors des ajouts ou suppressions.

Étape 2 — Afficher la liste avec \

Ajoutez l'affichage de la liste dans le template :


Bonne pratique - bind:checked pour les cases à cocher

bind:checked={article.coche} lie la case à cocher à la propriété coche de l'objet. Cocher la case modifie directement la propriété, et l'interface (comme le barré) se met à jour automatiquement.

Étape 3 — Ajouter un article

Ajoutez la fonction et le formulaire pour saisir un nouvel article :


Bonne pratique - Réinitialiser le champ après soumission

Toujours remettre le champ de saisie à vide (nouvelArticle = '') après avoir traité la valeur. L'utilisateur est prêt à saisir le suivant sans devoir effacer manuellement.

Étape 4 — Supprimer un article et afficher le compteur

Ajoutez la suppression et un décompte des articles non cochés avec $derived :


Bonne pratique - $derived pour les valeurs calculées

Utilisez $derived plutôt que de recalculer manuellement dans chaque fonction. Svelte garantit que la valeur est toujours synchronisée avec ses dépendances. C'est plus sûr et plus lisible que de mettre à jour articlesRestants dans ajouterArticle et supprimerArticle.

📌 Une solution