Svelte Reaktivität

6 Kernkonzepte
Die wichtigsten Reaktivitätskonzepte in Svelte: $: reaktive Statements · abgeleitete Werte · Stores · reaktive Arrays & Objekte · async Reaktivität · Tipps & Best Practices Svelte's Reaktivitätssystem ist das Herz des Frameworks. Es ermöglicht automatische DOM-Updates, wenn sich der Zustand ändert – ohne virtuelles DOM und ohne manuelle Aktualisierungen.

Reaktive Statements – $: Syntax

$: value = expression · $: { block }
let count = 0; $: doubled = count * 2; // Abgeleiteter Wert $: if (count > 5) { // Reaktiver Block console.log(`Count ist ${count}`); }

Reaktive Statements werden mit $: markiert und automatisch ausgeführt, wenn sich ihre Abhängigkeiten ändern. Sie können sowohl Ausdrücke als auch Code-Blöcke sein.

Beispiele
<script>
let firstName = "Anna";
let lastName = "Schmidt";
// Reaktiver abgeleiteter Wert
$: fullName = `${firstName} ${lastName}`;
// Reaktiver Block mit Bedingung
$: if (firstName.length > 0 && lastName.length > 0) {
console.log(`Vollständiger Name: ${fullName}`);
}
// Mehrere reaktive Statements
$: greeting = `Hallo ${firstName}`;
$: console.log(greeting);
</script>
<input bind:value={ firstName } placeholder="Vorname" />
<input bind:value={ lastName } placeholder="Nachname" />
<p>Vollständiger Name: { fullName }</p>
Tipp: Die Reihenfolge der reaktiven Statements spielt eine Rolle – sie werden in der Reihenfolge ihrer Deklaration ausgeführt. Stellen Sie sicher, dass Abhängigkeiten vor den abhängigen Statements deklariert werden.

Abgeleitete Werte – Berechnungen automatisch aktualisieren

$: derived = f(dependency)
let price = 100; let taxRate = 0.19; $: tax = price * taxRate; $: total = price + tax;

Abgeleitete Werte sind reaktive Variablen, die aus anderen Variablen berechnet werden. Sie aktualisieren sich automatisch, wenn sich die Abhängigkeiten ändern.

Beispiele
<script>
let items = ["Apfel", "Banane", "Kirsche"];
let filter = "";
// Gefilterte Liste – aktualisiert bei filter-Änderung
$: filteredItems = items.filter(item =>
item.toLowerCase().includes(filter.toLowerCase())
);
// Anzahl der gefilterten Items
$: count = filteredItems.length;
// Statusmeldung
$: status = count === 0 ? "Keine Treffer" : `${count} Treffer`;
</script>
<input bind:value={ filter } placeholder="Filtern..." />
<p>{ status }</p>
<ul>
{#each filteredItems as item}
<li>{ item }</li>
{/each}
</ul>
Tipp: Abgeleitete Werte sollten keine Seiteneffekte haben – sie sind reine Funktionen ihrer Abhängigkeiten. Für Seiteneffekte verwenden Sie reaktive Blöcke ($: { ... }).

Stores – Reaktivität über Komponenten hinweg

writable · readable · derived · $store
// store.js import { writable } from 'svelte/store'; export const user = writable({ name: "Anna" }); // In Komponente import { user } from './store.js'; $: console.log($user.name);

Stores sind der eingebaute Zustandsmanager von Svelte. Mit dem $-Präfix greifen Sie reaktiv auf den aktuellen Store-Wert zu.

Beispiele
// store.js
import { writable, derived } from 'svelte/store';
export const count = writable(0);
// Abgeleiteter Store
export const doubled = derived(count, $count => $count * 2);
// Component.svelte
<script>
import { count, doubled } from './store.js';
// Reaktiv auf Store-Änderungen reagieren
$: if ($count > 10) {
console.log("Count ist über 10!");
}
function increment() {
count.update(n => n + 1);
}
</script>
<button on:click={ increment }>
Count: { $count } (doubled: { $doubled })
</button>
Tipp: Das $-Präfix für Stores funktioniert nur im Top-Level des <script>-Blocks. Für die Verwendung in Funktionen verwenden Sie store.subscribe().

Reaktive Arrays & Objekte – Mutationen und Updates

array = [...array] · obj = { ...obj } · $: array
let todos = ["Einkaufen", "Lernen"]; // Reaktiv: todos ändert sich → DOM aktualisiert function addTodo() { todos = [...todos, "Neu"]; } function removeTodo(index) { todos = todos.filter((_, i) => i !== index); }

Reaktive Arrays und Objekte aktualisieren das DOM nur, wenn die Variable selbst neu zugewiesen wird. Mutationen (wie push oder obj.prop = value) lösen keine Aktualisierung aus – verwenden Sie die Spread-Syntax oder array = array.

Beispiele
<script>
let items = ["Apfel", "Banane", "Kirsche"];
let user = { name: "Anna", age: 30 };
$: console.log("Items geändert", items);
// Korrekte Array-Änderung (neue Zuweisung)
function addItem() {
items = [...items, "Dattel"];
}
function removeItem(index) {
items = items.filter((_, i) => i !== index);
}
// Korrekte Objekt-Änderung
function updateUser() {
user = { ...user, age: user.age + 1 };
}
</script>
<!-- items.map() wird bei Änderung neu gerendert -->
{#each items as item, i}
<li>
{ item }
<button on:click={ () => removeItem(i) }>X</button>
</li>
{/each}
<button on:click={ addItem }>Hinzufügen</button>
Tipp: Für große Arrays oder Objekte kann die Spread-Syntax ineffizient sein. In solchen Fällen verwenden Sie items = items nach einer Mutation, um die Reaktivität zu triggern (z.B. items.push('neu'); items = items;).

Async Reaktivität – Promises und async/await

async · await · $: promise
let data = null; let loading = false; $: fetchData(); async function fetchData() { loading = true; const response = await fetch('/api/data'); data = await response.json(); loading = false; }

Async Reaktivität kombiniert die $:-Syntax mit async/await für das Laden von Daten. Die reaktive Abhängigkeit löst den asynchronen Aufruf aus.

Beispiele
<script>
let userId = 1;
let userData = null;
let loading = false;
let error = null;
// Reaktiv bei userId-Änderung
$: loadUser(userId);
async function loadUser(id) {
loading = true;
error = null;
try {
const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
if (!res.ok) throw new Error('Fehler beim Laden');
userData = await res.json();
} catch (e) {
error = e.message;
} finally {
loading = false;
}
}
</script>
{#if loading}
<p>Lädt...</p>
{:else if error}
<p style="color: red">Fehler: { error }</p>
{:else if userData}
<p>Name: { userData.name }</p>
<p>Email: { userData.email }</p>
{/if}
Tipp: Die reaktive Abhängigkeit wird bei jeder Änderung von userId neu ausgelöst. Vermeiden Sie Seiteneffekte in $: – rufen Sie stattdessen asynchrone Funktionen auf.

Tipps & Best Practices – Reaktivität richtig nutzen

$: · tick · store · derived
// Warten auf DOM-Update import { tick } from 'svelte'; async function update() { count++; await tick(); /* DOM ist aktualisiert */ } // Reaktive Abhängigkeiten debuggen $: console.log({ count, doubled });

Tipps und Best Practices für die effiziente Nutzung der Svelte-Reaktivität – von Debugging bis zu Performance-Optimierungen.

Beispiele
// 1. tick() – DOM-Updates abwarten
import { tick } from 'svelte';
let scrollPosition = 0;
async function scrollToTop() {
scrollPosition = 0;
await tick();
// Jetzt ist das DOM aktualisiert
console.log("Scrollposition zurückgesetzt");
}
// 2. Reaktive Abhängigkeiten debuggen
let name = "Anna";
let age = 30;
$: console.log({ name, age }); // Loggt bei jeder Änderung
// 3. Vermeiden Sie Seiteneffekte in abgeleiteten Werten
// ❌ Schlecht: Seiteneffekt in abgeleitetem Wert
$: total = price * quantity; // Keine Seiteneffekte!
// ✅ Gut: Seiteneffekte in reaktivem Block
$: if (total > 100) { discount = true; }
// 4. Reaktivität mit Stores für globale Zustände
// Verwenden Sie Stores für Zustände, die von mehreren Komponenten benötigt werden
// Vermeiden Sie Prop-Drilling mit reaktiven Variablen
Tipp: tick() ist besonders nützlich, wenn Sie nach einer Zustandsänderung auf das aktualisierte DOM zugreifen müssen – z.B. für Animationen oder Messungen.

Svelte Reaktivität im Überblick

$: Reaktive Statements
Ausdrücke & Blöcke
derived Abgeleitete Werte
Automatische Aktualisierung
stores Globaler Zustand
writable, readable, derived
spread Arrays & Objekte
[...array], { ...obj }
async Asynchrone Reaktivität
API-Aufrufe, Daten laden
tick DOM-Updates abwarten
Nach Zustandsänderung

Quick Summary

$:
Reaktive Statements
derived
Abgeleitete Werte
stores
Globaler Zustand
[...]
Arrays & Objekte
async
Asynchrone Daten
tick
DOM-Updates
$: doubled = count * 2 · $: console.log(count) · await tick()