Skip to main content

svelte/reactivity

Svelte fournit des versions réactives de différentes classes natives comme Map, Set et URL, qui peuvent être utilisées exactement comme leur version native, ainsi qu’un certain nombre d’utilitaires permettant de bien gérer la réactivité.

import {
	MediaQuery,
	SvelteDate,
	SvelteMap,
	SvelteSet,
	SvelteURL,
	SvelteURLSearchParams,
	createSubscriber
} from 'svelte/reactivity';

MediaQuery

Disponible à partir de la version 5.7.0

Crée une media query et fournit une propriété current qui reflète si oui ou non celle-ci correspond.

Servez-vous en avec précaution — pendant le rendu côté serveur, il n’y a aucun moyen de connaître la valeur correcte, causant potentiellement des problèmes de contenu lors de l’hydratation. Si vous pouvez utiliser une media query en CSS pour obtenir le même résultat, faites-le.

<script>
	import { MediaQuery } from 'svelte/reactivity';

	const large = new MediaQuery('min-width: 800px');
</script>

<h1>{large.current ? 'écran large' : 'écran pas large'}</h1>
class MediaQuery extends ReactiveValue<boolean> {/*…*/}
constructor(query: string, fallback?: boolean | undefined);
  • query Une chaîne de caractères de media query
  • fallback Valeur de secours pour le serveur

SvelteDate

Une version réactive de l’objet natif Date. Lire une SvelteDate (que ce soit via des méthodes comme date.getTime() ou date.toString(), ou via des choses comme Intl.DateTimeFormat) dans un effet ou un dérivé va déclencher sa ré-évaluation lorsque la valeur de la date change.

<script>
	import { SvelteDate } from 'svelte/reactivity';

	const date = new SvelteDate();

	const formatter = new Intl.DateTimeFormat(undefined, {
	  hour: 'numeric',
	  minute: 'numeric',
	  second: 'numeric'
	});

	$effect(() => {
		const interval = setInterval(() => {
			date.setTime(Date.now());
		}, 1000);

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

<p>The time is {formatter.format(date)}</p>
class SvelteDate extends Date {/*…*/}
constructor(...params: any[]);

SvelteMap

Une version réactive de l’objet natif Map. Lire le contenu d’une SvelteMap (en itérant, ou en lisant map.size, ou en utilisant map.get(...). ou map.has(...) comme dans l’exemple de morpion ci-dessous) dans un effet ou un dérivé va déclencher sa ré-évaluation si nécessaire lors de la mise à jour de la map.

Notez que les valeurs au sein d’une map réactive ne sont pas rendues profondément réactives.

<script>
	import { SvelteMap } from 'svelte/reactivity';
	import { result } from './game.js';

	let board = new SvelteMap();
	let player = $state('x');
	let winner = $derived(result(board));

	function reset() {
		player = 'x';
		board.clear();
	}
</script>

<div class="board">
	{#each Array(9), i}
		<button
			disabled={board.has(i) || winner}
			onclick={() => {
				board.set(i, player);
				player = player === 'x' ? 'o' : 'x';
			}}
		>{board.get(i)}</button>
	{/each}
</div>

{#if winner}
	<p>{winner} gagne !</p>
	<button onclick={reset}>recommencer</button>
{:else}
	<p>C'est le tour de {player}</p>
{/if}
class SvelteMap<K, V> extends Map<K, V> {/*…*/}
constructor(value?: Iterable<readonly [K, V]> | null | undefined);
getOrInsert(key: K, value: V): V;
getOrInsertComputed(key: K, callbackFn: (key: K) => V): V;
set(key: K, value: V): this;

SvelteSet

Une version réactive de l’objet natif Set. Lire le contenu d’un SvelteSet (en itérant, ou en lisant set.size, ou en utilisant set.has(...) comme dans l’exemple ci-dessous) dans un effet ou un dérivé va déclencher sa ré-évaluation si nécessaire lors de la mise à jour du set.

Notez que les valeurs au sein d’un map réactif ne sont pas rendues profondément réactives.

<script>
	import { SvelteSet } from 'svelte/reactivity';
	let monkeys = new SvelteSet();

	function toggle(monkey) {
		if (monkeys.has(monkey)) {
			monkeys.delete(monkey);
		} else {
			monkeys.add(monkey);
		}
	}
</script>

{#each ['🙈', '🙉', '🙊'] as monkey}
	<button onclick={() => toggle(monkey)}>{monkey}</button>
{/each}

<button onclick={() => monkeys.clear()}>effacer</button>

{#if monkeys.has('🙈')}<p>ne pas voir le mal</p>{/if}
{#if monkeys.has('🙉')}<p>ne pas entendre le mal</p>{/if}
{#if monkeys.has('🙊')}<p>ne pas dire le mal</p>{/if}
class SvelteSet<T> extends Set<T> {/*…*/}
constructor(value?: Iterable<T> | null | undefined);
add(value: T): this;

SvelteURL

Une version réactive de l’objet natif URL. Lire des propriétés d’une SvelteURL (comme url.href ou url.pathname) dans un effet ou un dérivé va déclencher sa ré-évaluation si nécessaire lors de la mise à jour de l’url.

La propriété searchParams est une instance de SvelteURLSearchParams.

Exemple:

<script>
	import { SvelteURL } from 'svelte/reactivity';

	const url = new SvelteURL('https://example.com/path');
</script>

<!-- les changements produits ici... -->
<input bind:value={url.protocol} />
<input bind:value={url.hostname} />
<input bind:value={url.pathname} />

<hr />

<!-- vont mettre à jour `url.href` et inversement -->
<input bind:value={url.href} size="65" />
class SvelteURL extends URL {/*…*/}
get searchParams(): SvelteURLSearchParams;

SvelteURLSearchParams

Une version réactive de l’objet natif URLSearchParams. Lire le contenu d’un SvelteURLSearchParams (en itérant, ou en appelant params.get(...) ou params.getAll(...) comme dans l’exemple ci-dessous) dans un effet ou un dérivé va déclencher sa ré-évaluation si nécessaire lors de la mise à jour des paramètres de recherche.

<script>
	import { SvelteURLSearchParams } from 'svelte/reactivity';

	const params = new SvelteURLSearchParams('message=hello');

	let key = $state('key');
	let value = $state('value');
</script>

<input bind:value={key} />
<input bind:value={value} />
<button onclick={() => params.append(key, value)}>ajouter</button>

<p>?{params.toString()}</p>

{#each params as [key, value]}
	<p>{key}: {value}</p>
{/each}
class SvelteURLSearchParams extends URLSearchParams {/*…*/}
[REPLACE](params: URLSearchParams): void;

createSubscriber

Disponible à partir de la version 5.7.0

Renvoie une fonction subscribe qui intègre des systèmes externes basés sur des évènements dans la réactivité de Svelte. C’est particulièrement utile pour intégrer des APIs comme MediaQuery, IntersectionObserver, ou WebSocket.

Si subscribe est appelée au sein d’un effet (y compris indirectement, par exemple dans un getter), le callback start sera appelé avec une fonction update. À chaque fois que update est appelée, l’effet est ré-exécuté.

Si start renvoie une fonction de nettoyage, elle sera exécutée lors de la destruction de l’effet.

Si subscribe est appelée dans plusieurs effets, start ne sera appelé qu’une seule fois tant que les effets sont actifs, et la fonction de “destruction” renvoyée ne sera appelée que lorsque tous les effets concernées seront détruits.

On comprend mieux cette fonctionnalité avec un exemple. Voici l’implémentation de MediaQuery :

import { createSubscriber } from 'svelte/reactivity';
import { on } from 'svelte/events';

export class MediaQuery {
	#query;
	#subscribe;

	constructor(query) {
		this.#query = window.matchMedia(`(${query})`);

		this.#subscribe = createSubscriber((update) => {
			// lorsque l'évènement `change` se produit, rejoue tout effet qui lit `this.current`
			const off = on(this.#query, 'change', update);

			// arrête d'écouter lorsque tous les effets sont détruits
			return () => off();
		});
	}

	get current() {
		// This makes the getter reactive, if read in an effect
		this.#subscribe();

		// renvoie l'état courant de la query, que l'on soit ou non dans un effet
		return this.#query.matches;
	}
}
function createSubscriber(
	start: (update: () => void) => (() => void) | void
): () => void;

Modifier cette page sur Github llms.txt