Skip to main content

Stores

Un store est un objet qui permet des accès réactifs à une valeur via un simple contrat de store. Le module 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 $.

<script>
	import { writable } from 'svelte/store';

	const count = writable(0);
	console.log($count); // affiche 0

	count.set(1);
	console.log($count); // affiche 1

	$count = 2;
	console.log($count); // affiche 2
</script>

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
state.svelte
export const 
const userState: {
    name: string;
}
userState
=
function $state<{
    name: string;
}>(initial: {
    name: string;
}): {
    name: string;
} (+1 overload)
namespace $state

Declares reactive state.

Example:

let count = $state(0);
@see{@link https://svelte.dev/docs/svelte/$state Documentation}
@paraminitial The initial value
$state
({
name: stringname: 'nom', /* ... */ });
App
<script>
	import { userState } from './state.svelte.js';
</script>

<p>User name: {userState.name}</p>
<button onclick={() => {
	userState.name = 'nouveau nom';
}}>
	modifier le nom
</button>
<script lang="ts">
	import { userState } from './state.svelte.js';
</script>

<p>User name: {userState.name}</p>
<button onclick={() => {
	userState.name = 'nouveau nom';
}}>
	modifier le nom
</button>

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.

store
import { function writable<T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined): Writable<T>

Create a Writable store that allows both updating and reading by subscription.

@paramvalue initial value
writable
} from 'svelte/store';
const const count: Writable<number>count = writable<number>(value?: number | undefined, start?: StartStopNotifier<number> | undefined): Writable<number>

Create a Writable store that allows both updating and reading by subscription.

@paramvalue initial value
writable
(0);
const count: Writable<number>count.Readable<number>.subscribe(this: void, run: Subscriber<number>, invalidate?: () => void): Unsubscriber

Subscribe on value changes.

@paramrun subscription callback
@paraminvalidate cleanup callback
subscribe
((value: numbervalue) => {
var console: Consoleconsole.Console.log(...data: any[]): voidlog(value: numbervalue); }); // affiche '0' const count: Writable<number>count.Writable<number>.set(this: void, value: number): void

Set value and inform subscribers.

@paramvalue to set
set
(1); // affiche '1'
const count: Writable<number>count.Writable<number>.update(this: void, updater: Updater<number>): void

Update value using callback and inform subscribers.

@paramupdater callback
update
((n: numbern) => n: numbern + 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.

store
import { function writable<T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined): Writable<T>

Create a Writable store that allows both updating and reading by subscription.

@paramvalue initial value
writable
} from 'svelte/store';
const const count: Writable<number>count = writable<number>(value?: number | undefined, start?: StartStopNotifier<number> | undefined): Writable<number>

Create a Writable store that allows both updating and reading by subscription.

@paramvalue initial value
writable
(0, () => {
var console: Consoleconsole.Console.log(...data: any[]): voidlog('premier abonné'); return () => var console: Consoleconsole.Console.log(...data: any[]): voidlog('plus aucun abonné'); }); const count: Writable<number>count.Writable<number>.set(this: void, value: number): void

Set value and inform subscribers.

@paramvalue to set
set
(1); // rien ne se passe
const const unsubscribe: Unsubscriberunsubscribe = const count: Writable<number>count.Readable<number>.subscribe(this: void, run: Subscriber<number>, invalidate?: () => void): Unsubscriber

Subscribe on value changes.

@paramrun subscription callback
@paraminvalidate cleanup callback
subscribe
((value: numbervalue) => {
var console: Consoleconsole.Console.log(...data: any[]): voidlog(value: numbervalue); }); // affiche 'premier abonné', puis '1' const unsubscribe: () => voidunsubscribe(); // 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.

import { function readable<T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined): Readable<T>

Creates a Readable store that allows reading by subscription.

@paramvalue initial value
readable
} from 'svelte/store';
const const time: Readable<Date>time = readable<Date>(value?: Date | undefined, start?: StartStopNotifier<Date> | undefined): Readable<Date>

Creates a Readable store that allows reading by subscription.

@paramvalue initial value
readable
(new
var Date: DateConstructor
new () => Date (+4 overloads)
Date
(), (set: (value: Date) => voidset) => {
set: (value: Date) => voidset(new
var Date: DateConstructor
new () => Date (+4 overloads)
Date
());
const const interval: NodeJS.Timeoutinterval = function setInterval<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+1 overload)setInterval(() => { set: (value: Date) => voidset(new
var Date: DateConstructor
new () => Date (+4 overloads)
Date
());
}, 1000); return () => function clearInterval(timeout: NodeJS.Timeout | string | number | undefined): void (+1 overload)clearInterval(const interval: NodeJS.Timeoutinterval); }); const const ticktock: Readable<string>ticktock = readable<string>(value?: string | undefined, start?: StartStopNotifier<string> | undefined): Readable<string>

Creates a Readable store that allows reading by subscription.

@paramvalue initial value
readable
('tick', (set: (value: string) => voidset, update: (fn: Updater<string>) => voidupdate) => {
const const interval: NodeJS.Timeoutinterval = function setInterval<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+1 overload)setInterval(() => { update: (fn: Updater<string>) => voidupdate((sound: stringsound) => (sound: stringsound === 'tic' ? 'tac' : 'tic')); }, 1000); return () => function clearInterval(timeout: NodeJS.Timeout | string | number | undefined): void (+1 overload)clearInterval(const interval: NodeJS.Timeoutinterval); });

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.

import { function derived<S extends Stores, T>(stores: S, fn: (values: StoresValues<S>, set: (value: T) => void, update: (fn: Updater<T>) => void) => Unsubscriber | void, initial_value?: T | undefined): Readable<T> (+1 overload)

Derived value store by synchronizing one or more readable stores and applying an aggregation function over its input values.

derived
} from 'svelte/store';
const const doubled: Readable<number>doubled = derived<Writable<number>, number>(stores: Writable<number>, fn: (values: number) => number, initial_value?: number | undefined): Readable<number> (+1 overload)

Derived value store by synchronizing one or more readable stores and applying an aggregation function over its input values.

derived
(const a: Writable<number>a, ($a: number$a) => $a: number$a * 2);

Le callback peut définir une valeur de manière asynchrone en acceptant un deuxième argument, set, ainsi qu’un troisième argument optionnel, update, et en exécutant l’un ou l’autre lorsqu’approprié.

Dans ce cas, vous pouvez aussi passer un troisième argument à derived — la valeur initiale du store dérivé avant que set ou update ne soit exécuté pour la première fois. Si aucune valeur initiale n’est définie, la valeur initiale du store sera undefined.

import { function derived<S extends Stores, T>(stores: S, fn: (values: StoresValues<S>, set: (value: T) => void, update: (fn: Updater<T>) => void) => Unsubscriber | void, initial_value?: T | undefined): Readable<T> (+1 overload)

Derived value store by synchronizing one or more readable stores and applying an aggregation function over its input values.

derived
} from 'svelte/store';
const const delayed: Readable<number>delayed = derived<Writable<number>, number>(stores: Writable<number>, fn: (values: number, set: (value: number) => void, update: (fn: Updater<number>) => void) => Unsubscriber | void, initial_value?: number | undefined): Readable<...> (+1 overload)

Derived value store by synchronizing one or more readable stores and applying an aggregation function over its input values.

derived
(
const a: Writable<number>a, ($a: number$a, set: (value: number) => voidset) => { function setTimeout<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+1 overload)setTimeout(() => set: (value: number) => voidset($a: number$a), 1000); }, 2000 ); const const delayedIncrement: Readable<unknown>delayedIncrement = derived<Writable<number>, unknown>(stores: Writable<number>, fn: (values: number, set: (value: unknown) => void, update: (fn: Updater<unknown>) => void) => Unsubscriber | void, initial_value?: unknown): Readable<...> (+1 overload)

Derived value store by synchronizing one or more readable stores and applying an aggregation function over its input values.

derived
(const a: Writable<number>a, ($a: number$a, set: (value: unknown) => voidset, update: (fn: Updater<unknown>) => voidupdate) => {
set: (value: unknown) => voidset($a: number$a); function setTimeout<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+1 overload)setTimeout(() => update: (fn: Updater<unknown>) => voidupdate((x: unknownx) => x + 1), 1000); // chaque fois que $a change sa valeur, ceci met à jour le store // dérivé avec deux valeurs, $a immédiatement puis $a + 1 une seconde plus tard });

Si le callback renvoie une fonction, celle-ci sera exécutée a) juste avant que le callback soit de nouveau exécuté, ou lorsque b) le dernier abonné se désabonne.

import { function derived<S extends Stores, T>(stores: S, fn: (values: StoresValues<S>, set: (value: T) => void, update: (fn: Updater<T>) => void) => Unsubscriber | void, initial_value?: T | undefined): Readable<T> (+1 overload)

Derived value store by synchronizing one or more readable stores and applying an aggregation function over its input values.

derived
} from 'svelte/store';
const const tick: Readable<number>tick = derived<Writable<number>, number>(stores: Writable<number>, fn: (values: number, set: (value: number) => void, update: (fn: Updater<number>) => void) => Unsubscriber | void, initial_value?: number | undefined): Readable<...> (+1 overload)

Derived value store by synchronizing one or more readable stores and applying an aggregation function over its input values.

derived
(
const frequency: Writable<number>frequency, ($frequency: number$frequency, set: (value: number) => voidset) => { const const interval: NodeJS.Timeoutinterval = function setInterval<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+1 overload)setInterval(() => { set: (value: number) => voidset(var Date: DateConstructor

Enables basic storage and retrieval of dates and times.

Date
.DateConstructor.now(): number

Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC).

now
());
}, 1000 / $frequency: number$frequency); return () => { function clearInterval(timeout: NodeJS.Timeout | string | number | undefined): void (+1 overload)clearInterval(const interval: NodeJS.Timeoutinterval); }; }, 2000 );

Dans les deux cas, un tableau d’arguments peut être passé en premier argument à la place d’un seul et unique store.

import { function derived<S extends Stores, T>(stores: S, fn: (values: StoresValues<S>, set: (value: T) => void, update: (fn: Updater<T>) => void) => Unsubscriber | void, initial_value?: T | undefined): Readable<T> (+1 overload)

Derived value store by synchronizing one or more readable stores and applying an aggregation function over its input values.

derived
} from 'svelte/store';
const const summed: Readable<number>summed = derived<[Writable<number>, Writable<number>], number>(stores: [Writable<number>, Writable<number>], fn: (values: [number, number]) => number, initial_value?: number | undefined): Readable<...> (+1 overload)

Derived value store by synchronizing one or more readable stores and applying an aggregation function over its input values.

derived
([const a: Writable<number>a, const b: Writable<number>b], ([$a: number$a, $b: number$b]) => $a: number$a + $b: number$b);
const const delayed: Readable<unknown>delayed = derived<[Writable<number>, Writable<number>], unknown>(stores: [Writable<number>, Writable<number>], fn: (values: [number, number], set: (value: unknown) => void, update: (fn: Updater<...>) => void) => Unsubscriber | void, initial_value?: unknown): Readable<...> (+1 overload)

Derived value store by synchronizing one or more readable stores and applying an aggregation function over its input values.

derived
([const a: Writable<number>a, const b: Writable<number>b], ([$a: number$a, $b: number$b], set: (value: unknown) => voidset) => {
function setTimeout<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+1 overload)setTimeout(() => set: (value: unknown) => voidset($a: number$a + $b: number$b), 1000); });

readonly

Cette fonction est un simple utilitaire pour créer un store en lecture seule à partir d’un store existante. Vous pouvez toujours vous abonner aux changements du store original en utilisant le nouveau store.

import { function readonly<T>(store: Readable<T>): Readable<T>

Takes a store and returns a new one derived from the old one that is readable.

@paramstore - store to make readonly
readonly
, function writable<T>(value?: T | undefined, start?: StartStopNotifier<T> | undefined): Writable<T>

Create a Writable store that allows both updating and reading by subscription.

@paramvalue initial value
writable
} from 'svelte/store';
const const writableStore: Writable<number>writableStore = writable<number>(value?: number | undefined, start?: StartStopNotifier<number> | undefined): Writable<number>

Create a Writable store that allows both updating and reading by subscription.

@paramvalue initial value
writable
(1);
const const readableStore: Readable<number>readableStore = readonly<number>(store: Readable<number>): Readable<number>

Takes a store and returns a new one derived from the old one that is readable.

@paramstore - store to make readonly
readonly
(const writableStore: Writable<number>writableStore);
const readableStore: Readable<number>readableStore.Readable<number>.subscribe(this: void, run: Subscriber<number>, invalidate?: () => void): Unsubscriber

Subscribe on value changes.

@paramrun subscription callback
@paraminvalidate cleanup callback
subscribe
(var console: Consoleconsole.Console.log(...data: any[]): voidlog);
const writableStore: Writable<number>writableStore.Writable<number>.set(this: void, value: number): void

Set value and inform subscribers.

@paramvalue to set
set
(2); // console: 2
const readableStore: Readable<number>readableStore.set(2); // ERROR

get

En général, vous devriez lire la valeur d’un store en vous y abonnant et en vous servant de la valeur lorsque celle-ci évolue dans le temps. Occasionnellement, vous pourriez avoir besoin de récupérer la valeur d’un store auquel vous n’êtes pas abonné. get vous permet de faire cela.

Ceci fonctionne en créant un abonnement, en lisant la vvaleur, puis en se désabonnant. Il est donc recommandé de ne pas s’en servir dans du code pouvant impacter la performance.

import { function get<T>(store: Readable<T>): T

Get the current value from a store by subscribing and immediately unsubscribing.

get
} from 'svelte/store';
const const value: stringvalue = get<string>(store: Readable<string>): string

Get the current value from a store by subscribing and immediately unsubscribing.

get
(const store: Writable<string>store);

Contrat de store

store = { subscribe: (subscription: (value: any) => void) => () => undefinedsubscribe: (subscription: (value: any) => voidsubscription: (value: anyvalue: any) => void) => (() => void), set: (value: any) => undefinedset?: (value: anyvalue: any) => void }

Vous pouvez créer vos propres stores sans vous baser sur svelte/store, en implémentant le contrat de store vous-même :

  1. Un store doit contenir une méthode .subscribe, qui doit accepter en argument une fonction d’abonnement. Cette fonction d’abonnement doit être exécutée immédiatement et de manière synchrone avec la valeur plus récente du store lorsque .subscribe est appelée. Toutes les fonctions d’abonnement actives d’un store doivent ensuite être appelées de manière synchrone lorsque la valeur du store est mise à jour.
  2. La méthode .subscribe doit renvoyer une fonction de désabonnement. Exécuter une fonction de désabonnement doit arrêter son abonnement, et la fonction d’abonnement correspondante ne doit ensuite plus être appelée par le store.
  3. Un store peut optionnellement contenir une méthode .set, qui doit accepter en argument une nouvelle valeur pour le store, et qui appellera de manière synchrone toutes les fonctions d’abonnement actives du store. Un tel store est appelé un store d’écriture.

Pour des raisons d’interopérabilité avec les Observables de RxJs, la méthode .subscribe est aussi autorisée à renvoyer un objet avec une méthode .unsubscribe, plutôt que de renvoyer directement une fonction de désabonnement. Notez cependant qu’à moins que .subscribe n’appelle de manière synchrone la fonction d’abonnement (ce qui n’est pas requis par la spécification d’Observable), Svelte verra la valeur du store comme étant undefined, et ce jusqu’à ce que la fonction d’abonnement soit exécutée.

Modifier cette page sur Github llms.txt

précédent suivant