Un _store_ est un objet qui permet des accès réactifs à une valeur via un simple _contrat de store_. Le [module `svelte/store`](../svelte-store) contient des implémentations minimales de stores satisfaisant ce contrat. Chaque fois que vous avez une référence à un store, vous pouvez accéder à sa valeur au sein d'un composant en utilisant le caractère `$`. Ceci va indiquer à Svelte qu'il doit déclarer la variable préfixée, s'abonner aux changements du store au moment de l'initialisation du composant, et s'en désabonner lorsqu'approprié. Les assignations à des variables préfixées avec `$` nécessitent que la variable non préfixée soit un store d'écriture, et va conduire à un appel à la méthode `.set` du store. Notez que le store doit être déclaré à la racine du composant — et non dans un bloc `#if` ou une fonction, par exemple. Les variables locales (qui ne représentent pas des valeurs de store) ne doivent _pas_ être préfixées pas `$`. ```svelte ``` ## Quand utiliser des stores Avant Svelte 5, les stores étaient la solution à utiliser pour créer des états réactifs accessibles dans différents composant, ou bien pour factoriser de la logique. Avec les runes, les besoins d'utilisation de stores se sont grandement réduits. - lorsque vous voulez factoriser de la logique, il est plus efficace de tirer profit de la réactivité universelle des runes : vous pouvez utiliser les runes en dehors de la racine d'un composant, et même vous en servir dans des fichiers JavaScript ou TypeScript (en utilisant les extensions `.svelte.js` ou `.svelte.ts`) - lorsque vous voulez créer un état partagé, vous pouvez créer un objet `$state` contenant les valeurs dont vous avez besoin et ensuite manipuler cet état ```ts /// file: state.svelte.js export const userState = $state({ name: 'nom', /* ... */ }); ``` ```svelte
User name: {userState.name}
``` Les stores sont toujours une bonne solution lorsque vous avez des flux de données asynchrones complexes, ou lorsqu'il est important que vous contrôliez manuellement la mise à jour des valeurs ou l'écoute des changements. Si vous êtes familier•e•s de RxJs et souhaitez vous servir de ces connaissances, le `$` peut être pratique pour vous. ## svelte/store Le module `svelte/store` contient une implémentation de store minimale qui satisfait le contrat de store. Il fournit des méthodes pour créer des stores que vous pouvez mettre à jour depuis l'extérieur, des stores que vous pouvez créer depuis l'intérieur, et des méthodes pour combiner et dériver des stores. ### `writable` Fonction qui crée un store dont les valeurs peuvent être définies depuis l'"extérieur" des composants. Ils sont créés en tant qu'objets avec des méthodes additionnelles `set` et `update`. `set` est une méthode qui prend un argument qui est la valeur à définir. La valeur du store devient la valeur de passée en argument si la valeur du store n'est pas déjà égale à cette valeur. `update` est une méthode qui prend un callback en argument. Le callback prend la valeur existante du store comme argument et renvoie une nouvelle valeur définissant la nouvelle valeur du store. ```js /// file: store.js import { writable } from 'svelte/store'; const count = writable(0); count.subscribe((value) => { console.log(value); }); // affiche '0' count.set(1); // affiche '1' count.update((n) => n + 1); // affiche '2' ``` Si une fonction est passée en deuxième argument, elle sera exécutée lorsque le nombre d'abonnés passe de zéro à un (mais pas de un à deux, etc.). Cette fonction a comme arguments une fonction `set` qui change la valeur du store, et une fonction `update` qui fonctionne comme la méthode `update` du store, prenant un callback en argument pour calculer la nouvelle valeur du store à partir de l'ancienne valeur. Cette fonction doit renvoyer une fonction `stop` qui sera appelée lorsque le nombre d'abonnés passe de un à zéro. ```js /// file: store.js import { writable } from 'svelte/store'; const count = writable(0, () => { console.log('premier abonné'); return () => console.log('plus aucun abonné'); }); count.set(1); // rien ne se passe const unsubscribe = count.subscribe((value) => { console.log(value); }); // affiche 'premier abonné', puis '1' unsubscribe(); // affiche 'plus aucun abonné' ``` Notez que la valeur de `writable` est perdue lorsque celui-ci est détruit, par exemple lorsque la page est rafraîchie. Cependant, vous pouvez ecrire votre propre logique pour synchroniser la valeur avec par exemple le `localStorage`. ### `readable` Crée un store dont la valeur ne peut être lue depuis l'"extérieur" ; le premier argument est la valeur initiale du store, le deuxième argument est le même que le deuxième argument de `writable`. ```ts import { readable } from 'svelte/store'; const time = readable(new Date(), (set) => { set(new Date()); const interval = setInterval(() => { set(new Date()); }, 1000); return () => clearInterval(interval); }); const ticktock = readable('tick', (set, update) => { const interval = setInterval(() => { update((sound) => (sound === 'tic' ? 'tac' : 'tic')); }, 1000); return () => clearInterval(interval); }); ``` ### `derived` Crée un store qui dérive d'un ou plusieurs stores. Le callback est exécuté une première fois lorsque le premier abonné s'abonne, et à chaque fois que les dépendances du store changent de valeur. Dans la version la plus simple, `derived` prend un seul store, et le callback renvoie une valeur dérivée. ```ts // @filename: ambient.d.ts import { type Writable } from 'svelte/store'; declare global { const a: Writable