In the previous lesson, you learned how to create reusable code blocks using snippets in Svelte. This allowed you to build modular and scalable components by defining reusable templates and rendering them dynamically. Now, we’ll shift our focus to another essential aspect of Svelte: lifecycle effects.
Lifecycle effects are actions that occur at specific stages of a component’s existence, such as when it is first rendered or when it is removed from the DOM. Managing these effects is crucial for tasks like fetching data, setting up event listeners, and cleaning up resources to avoid memory leaks. In Svelte, lifecycle effects are handled using two key functions: onMount
and onDestroy
.
In this lesson, you’ll learn how to use onMount
to perform actions when a component is first rendered and onDestroy
to clean up resources when a component is removed from the DOM. By the end of this lesson, you’ll be able to manage lifecycle effects effectively in your Svelte applications.
The onMount
function is used to perform actions when a component is first rendered. This is particularly useful for tasks like fetching data from an API or setting up event listeners. Let’s look at an example where we fetch user data when the component is mounted.
Here’s how you can use onMount
to fetch user data:
svelte1<script> 2 import { onMount } from 'svelte'; 3 4 let user = $state(null); 5 let isLoading = $state(true); 6 let error = $state(null); 7 8 onMount(async () => { 9 try { 10 const response = await fetch("https://jsonplaceholder.typicode.com/users/1"); 11 if (!response.ok) { 12 throw new Error(`HTTP error! status: ${response.status}`); 13 } 14 user = await response.json(); 15 } catch (err) { 16 error = err.message; 17 } finally { 18 isLoading = false; 19 } 20 }); 21</script> 22 23{#if isLoading} 24 <p>Loading user data...</p> 25{:else if error} 26 <p>Error: {error}</p> 27{:else if user} 28 <h2>{user.name}</h2> 29 <p>Email: {user.email}</p> 30 <p>Phone: {user.phone}</p> 31{/if}
In this example:
- We import
onMount
from Svelte and define reactive state variables using$state
. - Inside
onMount
, we fetch user data from an API. If the fetch is successful, we store the user data in theuser
variable. If there’s an error, we store the error message in theerror
variable. - Finally, we set
isLoading
tofalse
to indicate that the data fetching is complete.
The component renders a loading message while the data is being fetched, an error message if something goes wrong, and the user’s details once the data is successfully fetched.
The onDestroy
function is used to clean up resources when a component is removed from the DOM. This is essential for tasks like clearing intervals, unsubscribing from services, or cleaning up other browser-specific resources. Let’s extend our previous example to include a simple timer that updates every second.
Here’s how you can use onDestroy
to clean up an interval:
svelte1<script> 2 import { onMount, onDestroy } from 'svelte'; 3 4 let time = $state(new Date().toLocaleTimeString()); 5 let intervalId; 6 7 onMount(() => { 8 // Set up the interval when the component is mounted 9 intervalId = setInterval(() => { 10 time = new Date().toLocaleTimeString(); 11 }, 1000); 12 }); 13 14 onDestroy(() => { 15 // Clean up the interval when the component is destroyed 16 clearInterval(intervalId); 17 }); 18</script> 19 20<h2>Current Time:</h2> 21<p>{time}</p>
In this example:
- We set up a
setInterval
function inonMount
to update thetime
variable every second. - In
onDestroy
, we clear the interval usingclearInterval()
to ensure no memory leaks occur when the component is destroyed.
This ensures that the interval is properly cleaned up, preventing potential memory leaks.
⚠️ Warning: Be cautious when using
onDestroy
to interact with browser-specific objects likewindow
,document
, orlocalStorage
. SinceonDestroy
can run during Server-Side Rendering (SSR), trying to access these objects directly will cause errors.
In many cases, you’ll need to combine onMount
and onDestroy
to manage lifecycle effects effectively. Let’s revisit our example to see how these two functions work together.
Here’s the complete code for fetching user data and setting up a WebSocket connection:
svelte1<script> 2 import { onMount, onDestroy } from 'svelte'; 3 4 let user = $state(null); 5 let isLoading = $state(true); 6 let error = $state(null); 7 let socketMessage = $state(null); 8 let socket; 9 10 onMount(async () => { 11 // Create a WebSocket connection 12 socket = new WebSocket('wss://example.com/socket'); 13 14 // Listen for incoming messages 15 socket.onmessage = (event) => { 16 socketMessage = event.data; 17 }; 18 19 // Fetch user data 20 try { 21 const response = await fetch("https://jsonplaceholder.typicode.com/users/1"); 22 if (!response.ok) { 23 throw new Error(`HTTP error! status: ${response.status}`); 24 } 25 user = await response.json(); 26 } catch (err) { 27 error = err.message; 28 } finally { 29 isLoading = false; 30 } 31 }); 32 33 onDestroy(() => { 34 // Close the WebSocket connection when the component is destroyed 35 if (socket) { 36 socket.close(); 37 } 38 }); 39</script> 40 41{#if isLoading} 42 <p>Loading user data...</p> 43{:else if error} 44 <p>Error: {error}</p> 45{:else if user} 46 <h2>{user.name}</h2> 47 <p>Email: {user.email}</p> 48 <p>Phone: {user.phone}</p> 49{/if} 50 51<h2>WebSocket Message:</h2> 52<p>{socketMessage ? socketMessage : "Waiting for messages..."}</p>
In this example:
- We use
onMount
to fetch user data and establish a WebSocket connection to receive real-time messages. - We use
onDestroy
to properly close the WebSocket connection when the component is destroyed, ensuring there are no memory leaks or unintended network usage. - The component displays the user’s details and the latest message received from the WebSocket server, updating dynamically as messages are received.
In this lesson, you’ve learned how to manage lifecycle effects in Svelte using onMount
and onDestroy
. We covered how to fetch data when a component is mounted, set up event listeners, and clean up resources when a component is destroyed. You also saw how to combine these functions to handle complex lifecycle scenarios.
In the upcoming practice exercises, you’ll apply these concepts to manage lifecycle effects in real-world scenarios. You’ll focus on fetching data, handling cleanup, and managing reactive state. Remember to experiment with the code and explore further to deepen your understanding of lifecycle effects in Svelte.
Great job completing this lesson! You’re now ready to take on the challenges of managing lifecycle effects in Svelte. Keep up the good work!