$state
Utilisez la rune $state uniquement pour les variables qui doivent être réactives — autrement dit, les variables qui déclenchent une mise à jour dans $effect, $derived ou une expression template. Tout le reste peut être une variable normale.
Les objets et tableaux ($state({...}) ou $state([...])) sont rendus profondément réactifs, ce qui signifie que les mutations déclencheront des mises à jour. Cela a un coût : en échange d'une réactivité fine, les objets doivent être proxifiés, ce qui a un surcoût de performance. Dans les cas où vous avez affaire à de grands objets qui ne sont jamais que réassignés (plutôt que mutés), utilisez $state.raw à la place. C'est souvent le cas avec les réponses API, par exemple.
$derived
Pour calculer quelque chose à partir de l'état, utilisez $derived plutôt que $effect :
// faites ceci
let square = $derived(num * num);
// ne faites pas ceci
let square;
$effect(() => {
square = num * num;
});
[!NOTE]
$derivedreçoit une expression, pas une fonction. Si vous avez besoin d'utiliser une fonction (parce que l'expression est complexe, par exemple) utilisez$derived.by.
Les dérivés sont modifiables — vous pouvez leur assigner une valeur, tout comme $state, sauf qu'ils seront réévalués quand leur expression change.
Si l'expression du dérivé est un objet ou un tableau, il sera retourné tel quel — il n'est pas rendu profondément réactif. Vous pouvez cependant utiliser $state à l'intérieur de $derived.by dans les rares cas où vous en auriez besoin.
$effect
Les effets sont une échappatoire et doivent être évités dans la plupart des cas. En particulier, évitez de mettre à jour l'état à l'intérieur des effets.
- Si vous avez besoin de synchroniser l'état avec une bibliothèque externe comme D3, il est souvent plus propre d'utiliser
{@attach ...} - Si vous avez besoin d'exécuter du code en réponse à une interaction utilisateur, mettez le code directement dans un gestionnaire d'événement ou utilisez un function binding selon le cas
- Si vous avez besoin de enregistrer des valeurs à des fins de débogage, utilisez
$inspect - Si vous avez besoin d'observer quelque chose d'externe à Svelte, utilisez
createSubscriber
N'enrobez jamais le contenu d'un effet dans if (browser) {...} ou similaire — les effets ne s'exécutent pas sur le serveur.
$props
Traitez les props comme si elles allaient changer. Par exemple, les valeurs qui dépendent des props doivent généralement utiliser $derived :
// @errors: 2451
let { type } = $props();
// faites ceci
let color = $derived(type === 'danger' ? 'red' : 'green');
// ne faites pas ceci — `color` ne sera pas mise à jour si `type` change
let color = type === 'danger' ? 'red' : 'green';
$inspect.trace
$inspect.trace est un outil de débogage pour la réactivité. Si quelque chose ne se met pas à jour correctement ou s'exécute plus qu'il ne le devrait, vous pouvez ajouter $inspect.trace(label) comme première ligne d'un $effect ou $derived.by (ou de toute fonction qu'ils appellent) pour tracer leurs dépendances et découvrir laquelle a déclenché une mise à jour.
Événements
Tout attribut d'élément commençant par on est traité comme un gestionnaire d'événement :
<button onclick={() => {...}}>click me</button>
<!-- le raccourci d'attribut fonctionne aussi -->
<button {onclick}>...</button>
<!-- tout comme les attributs propagés -->
<button {...props}>...</button>
Si vous avez besoin d'attacher des écouteurs à window ou document vous pouvez utiliser <svelte:window> et <svelte:document> :
<svelte:window onkeydown={...} />
<svelte:document onvisibilitychange={...} />
Évitez d'utiliser onMount ou $effect pour cela.
Snippets
Les snippets sont un moyen de définir des blocs de markup réutilisables qui peuvent être instanciés avec la balise {@render ...}, ou passés aux composants en tant que props. Ils doivent être déclarés dans le template.
{#snippet greeting(name)}
<p>hello {name}!</p>
{/snippet}
{@render greeting('world')}
[!NOTE] Les snippets déclarés au niveau supérieur d'un composant (c'est-à-dire pas à l'intérieur d'éléments ou de blocs) peuvent être référencés à l'intérieur de
<script>. Un snippet qui ne référence pas l'état du composant est également disponible dans un<script module>, auquel cas il peut être exporté pour utilisation par d'autres composants.
Blocs each
Préférez utiliser des blocs each avec clé — cela améliore les performances en permettant à Svelte d'insérer ou supprimer chirurgicalement des éléments plutôt que de mettre à jour le DOM appartenant aux éléments existants.
[!NOTE] La clé doit identifier uniquement l'objet. N'utilisez pas l'index comme clé.
Évitez de destructurer si vous avez besoin de muter l'élément (avec quelque chose comme bind:value={item.count}, par exemple).
Utiliser des variables JavaScript en CSS
Si vous avez une variable JS que vous voulez utiliser à l'intérieur du CSS, vous pouvez définir une propriété personnalisée CSS avec la directive style:.
<div style:--columns={columns}>...</div>
Vous pouvez alors référencer var(--columns) à l'intérieur du <style> du composant.
Styliser les composants enfants
Le CSS dans le <style> d'un composant est limité à ce composant. Si un composant parent doit contrôler les styles de l'enfant, la manière préférée est d'utiliser les propriétés personnalisées CSS :
<!-- Parent.svelte -->
<Child --color="red" />
<!-- Child.svelte -->
<h1>Hello</h1>
<style>
h1 {
color: var(--color);
}
</style>
Si cela est impossible (par exemple, le composant enfant provient d'une bibliothèque) vous pouvez utiliser :global pour remplacer les styles :
<div>
<Child />
</div>
<style>
div :global {
h1 {
color: red;
}
}
</style>
Context
Envisagez d'utiliser context au lieu de déclarer l'état dans un module partagé. Cela limitera l'état à la partie de l'application qui en a besoin, et éliminera la possibilité qu'il ne s'échappe entre les utilisateurs lors du rendu côté serveur.
Utilisez createContext plutôt que setContext et getContext, car il fournit la sécurité des types.
Async Svelte
Si vous utilisez la version 5.36 ou supérieure, vous pouvez utiliser les await expressions et hydratable pour utiliser les promesses directement à l'intérieur des composants. Notez que celles-ci nécessitent que l'option experimental.async soit activée dans svelte.config.js car elles ne sont pas encore considérées comme totalement stables.
Éviter les fonctionnalités héritées
Utilisez toujours le mode runes pour le nouveau code, et évitez les fonctionnalités qui ont des remplaçants plus modernes :
- utilisez
$stateau lieu de la réactivité implicite (par ex.let count = 0; count += 1) - utilisez
$derivedet$effectau lieu des assignations et statements$:(mais utilisez les effets uniquement quand il n'y a pas de meilleure solution) - utilisez
$propsau lieu deexport let,$$propset$$restProps - utilisez
onclick={...}au lieu deon:click={...} - utilisez
{#snippet ...}et{@render ...}au lieu de<slot>,$$slotset<svelte:fragment> - utilisez
<DynamicComponent>au lieu de<svelte:component this={DynamicComponent}> - utilisez
import Self from './ThisComponent.svelte'et<Self>au lieu de<svelte:self> - utilisez les classes avec champs
$statepour partager la réactivité entre composants, au lieu d'utiliser les stores - utilisez
{@attach ...}au lieu deuse:action - utilisez des tableaux et objets de style clsx dans les attributs
class, au lieu de la directiveclass: