$derived
Vous pouvez déclarer un état dérivé avec la rune $derived
:
<script>
let count = $state(0);
let doubled = $derived(count * 2);
</script>
<button onclick={() => count++}>
{doubled}
</button>
<p>Le double de {count} vaut {doubled}</p>
L’expression à l’intérieur de $derived(...)
ne doit pas contenir d’effet de bord. Svelte empêchera
les changements d’état (par ex. count++
) à l’intérieur d’expressions dérivées.
Comme avec $state
, vous pouvez définir les champs d’une classe en utilisant $derived
.
Le code d’un composant Svelte est uniquement exécuté à sa création. Sans la rune
$derived
,doubled
maintiendrait sa valeur originale même sicount
change de valeur.
$derived.by
Parfois, certaines derivations complexes nécessitent plus qu’une simple expression. Dans ces cas là,
vous pouvez utiliser $derived.by
, qui prend une fonction comme argument.
<script>
let numbers = $state([1, 2, 3]);
let total = $derived.by(() => {
let total = 0;
for (const n of numbers) {
total += n;
}
return total;
});
</script>
<button onclick={() => numbers.push(numbers.length + 1)}>
{numbers.join(' + ')} = {total}
</button>
Par essence, $derived(expression)
est équivalent à $derived.by(() => expression)
.
Comprendre les dépendences
Tout ce qui est lu de manière synchrone au de l’expression de $derived
(ou du corps de la fonction
de $derived.by
) est considérée comme une dépendence de l’état dérivé. Lorsqu’un des états dont
il dépend est mis à jour, l’état dérivé sera marqué comme sale et recalculé la prochaine fois que
sa valeur est lue.
Pour exempter un morceau d’état d’être considéré comme une dépendance, utilisez
untrack
.
Propagation de la mise à jour
Svelte utilise un concept appelée réactivité push-pull — lorsque l’état est mis à jour, tout ce qui dépend de l’état (directement ou non) est immédiatement notifié du changement (le ‘push’), mais les valeurs dérivées ne sont pas ré-évaluées tant qu’elles ne sont lues (le ‘pull’).
Si la nouvelle valeur d’un état dérivé est identique en termes de référence que la valeur
précédente, les mises à jour en aval seront ignorées. Autrement dit, Svelte ne mettra à jour le
texte au sein du bouton que lorsque large
change, pas lorsque count
change, même si large
dépend de count
:
<script>
let count = $state(0);
let large = $derived(count > 10);
</script>
<button onclick={() => count++}>
{large}
</button>