Lesson 3
Handling Lifecycle Effects with onMount and onDestroy
Introduction to Lifecycle Effects in Svelte

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.

Using `onMount` for Initialization

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:

svelte
1<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 the user variable. If there’s an error, we store the error message in the error variable.
  • Finally, we set isLoading to false 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.

Using `onDestroy` for Cleanup

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:

svelte
1<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 in onMount to update the time variable every second.
  • In onDestroy, we clear the interval using clearInterval() 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 like window, document, or localStorage. Since onDestroy can run during Server-Side Rendering (SSR), trying to access these objects directly will cause errors.

Combining `onMount` and `onDestroy`

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:

svelte
1<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.
Summary and Practice Preparation

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!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.