Kurs Svelte i SvelteKit · Moduł 7: Cykl życia
Walhalla - Cykl życia komponentów
W tej lekcji4
Witaj w Walhalli! Jak wojownicy przybywają i odchodzą z tych sal, tak komponenty mają swój cykl życia - od powstania do zniszczenia.
Lifecycle w Svelte
Komponent tworzony
↓
onMount() ← Zamontowany w DOM
↓
[życie] ← $effect.pre / $effect przy zmianach stanu
↓
onDestroy() ← Usuwany z DOMW Svelte 5 nie ma hooków uruchamianych przy każdej aktualizacji całego komponentu. Zamiast nich efekty ($effect.pre, $effect) reagują tylko na stan, którego używają - poznasz je dokładniej w następnej lekcji.
onMount - Przybycie do Walhalli
<script>
import { onMount } from 'svelte';
let data = $state(null);
onMount(() => {
console.log('Komponent zamontowany!');
// Fetch danych
fetch('/api/warriors')
.then(r => r.json())
.then(d => data = d);
// Cleanup (opcjonalny)
return () => {
console.log('Komponent będzie odmontowany');
};
});
</script>onDestroy - Odejście na Ragnarök
<script>
import { onDestroy } from 'svelte';
const interval = setInterval(() => {
console.log('tick');
}, 1000);
onDestroy(() => {
clearInterval(interval);
console.log('Posprzątano!');
});
</script>Svelte 5: $effect z funkcją sprzątającą
$effect uruchamia się po zamontowaniu komponentu, a funkcja, którą zwraca, sprząta przy odmontowaniu. Efekt, który nie czyta żadnego stanu, działa raz - jak onMount i onDestroy w jednym:
<script>
// Efekt nie czyta stanu, więc uruchomi się raz po zamontowaniu
$effect(() => {
console.log('Zamontowany!');
const interval = setInterval(() => {
console.log('tick');
}, 1000);
return () => {
clearInterval(interval);
console.log('Odmontowany!');
};
});
</script>Gdy efekt czyta stan (np. count), uruchamia się ponownie po każdej jego zmianie, a przed każdym kolejnym uruchomieniem wywołuje swoją funkcję sprzątającą. Do kodu, który ma zadziałać dokładnie raz, onMount nadal jest dobrym wyborem.
Życie w Walhalli ma swój rytm - tak jak lifecycle komponentów!
Kod do tej lekcji: App.svelte
<script>
// Walhalla - Cykl życia komponentów
// onMount, onDestroy i $effect z funkcją sprzątającą
import { onMount, untrack } from 'svelte';
import Einherjar from './Einherjar.svelte';
let mounted = $state(false);
let showWarrior = $state(true);
let logs = $state([]);
// untrack: log można wywołać nawet z efektu, a zapis do logs
// nie stanie się jego zależnością (więcej w lekcji 7_2)
function log(message) {
untrack(() => {
logs = [...logs, { time: new Date().toLocaleTimeString(), message }].slice(-8);
});
}
onMount(() => {
mounted = true;
log('onMount (App) - Walhalla otwiera wrota');
});
</script>
<main class="lifecycle">
<h1>Walhalla - Cykl Życia</h1>
<p class="subtitle">onMount, onDestroy, $effect</p>
<section>
<h2>Status</h2>
<p>App zamontowany: <strong>{mounted ? 'Tak' : 'Nie'}</strong></p>
<button onclick={() => (showWarrior = !showWarrior)}>
{showWarrior ? 'Wyślij wojownika na Ragnarök' : 'Przywołaj wojownika'}
</button>
</section>
{#if showWarrior}
<Einherjar onLog={log} />
{:else}
<p class="empty">Wojownik odszedł. Przywołaj go, aby znów zobaczyć onMount.</p>
{/if}
<section class="logs">
<h2>Logi cyklu życia</h2>
{#each logs as entry}
<p><span class="time">{entry.time}</span> {entry.message}</p>
{/each}
</section>
</main>
<style>
.lifecycle {
font-family: 'Georgia', serif;
max-width: 600px;
margin: 0 auto;
padding: 2rem;
background: linear-gradient(135deg, #1a0a0a 0%, #2a1a0a 100%);
color: #e8d5b7;
min-height: 100vh;
}
h1 {
color: #ffd700;
text-align: center;
}
.subtitle {
text-align: center;
color: #8b7355;
}
section {
background: rgba(212, 175, 55, 0.1);
border: 1px solid #d4af37;
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
}
h2 {
color: #d4af37;
font-size: 1rem;
margin-top: 0;
}
strong {
color: #ffd700;
}
button {
padding: 0.5rem 1rem;
background: #3d2914;
color: #e8d5b7;
border: 1px solid #d4af37;
border-radius: 4px;
cursor: pointer;
}
.empty {
color: #8b7355;
font-style: italic;
}
.logs {
max-height: 250px;
overflow-y: auto;
}
.logs p {
margin: 0.25rem 0;
padding: 0.25rem 0.5rem;
background: rgba(0,0,0,0.3);
border-radius: 4px;
font-size: 0.9rem;
}
.time {
color: #8b7355;
font-family: monospace;
margin-right: 0.5rem;
}
</style>Hasła z dokumentacji w tej lekcji
Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Kiedy wywoływana jest funkcja onMount?
2. Jak wykonać cleanup w onMount?