Mastering Conditional Rendering and Lists in Svelte
In the previous assignment, you had the task of creating a counter and exploring the functionality of components in Svelte. Today, our focus will shift towards mastering the art of conditionally rendering components and efficiently rendering lists using loops.
if you haven't read part 1 and 2 check
https://joeljaison.hashnode.dev/unlocking-the-power-of-svelte-mastering-bindings
https://joeljaison.hashnode.dev/getting-started-with-svelte-a-comprehensive-tutorial-series
Conditional Rendering in Svelte
Conditional rendering is a crucial concept in web development, allowing us to display different content based on certain conditions. In Svelte, this is quite straightforward thanks to its clean and intuitive syntax.
Basic Conditional Rendering
Let's start with the basics. To conditionally render content in Svelte, we use the {#if}
and {/if}
blocks. Here's an example:
<script>
let showContent = true;
</script>
{#if showContent}
<p>This content will only display if showContent is true.</p>
{/if}
In this code, the paragraph will be shown only if showContent
is true
.
Conditional Rendering with else
Sometimes, you want to display one thing when a condition is true and something else when it's false. Svelte allows you to do this with the {:else}
block:
<script>
let loggedIn = true;
</script>
{#if loggedIn}
<p>Welcome, user!</p>
{:else}
<p>Please log in.</p>
{/if}
Here, if loggedIn
is true
, it will display the welcome message, and if loggedIn
is false
, it will display the login prompt.
Conditional Rendering with Ternary Operator
If you have a simple conditional, you can use a ternary operator for a concise syntax:
<script>
let isLoggedIn = false;
</script>
{isLoggedIn ? (
<p>Welcome, user!</p>
) : (
<p>Please log in.</p>
)}
This code achieves the same result as the previous example but with a more compact format.
Ticket Pricing for the Fun Ride
Now, let's apply our knowledge of conditional rendering to a real-world scenario: pricing tickets for a fun ride. Our pricing scheme is as follows:
Children below 10 years: $5
Children between 10 and 20 years: $10
Teenagers and young adults up to 60 years: $15
Children below 5 years and adults above 60 years: Not allowed to enter.
<script> let age = 0; let ticketPrice; let showTicket = false; let name = ""; function calculateTicketPrice() { if (age < 5 || age > 60) { ticketPrice = null; } else if (age < 10) { ticketPrice = 5; } else if (age >= 10 && age <= 20) { ticketPrice = 10; } else if (age <= 60) { ticketPrice = 15; } return ticketPrice; } </script> <div class="container mx-auto p-4"> <h1 class="text-3xl font-semibold mb-4 underline">Fun Ride Ticket Pricing</h1> <div class="mb-4"> <label for="name" class="block text-gray-700 text-xl p-2">Enter your name:</label> <input type="text" id="name" name="name" placeholder="Name" class="border rounded-lg p-4 w-50" bind:value={name} /> <label for="age" class="block text-gray-700 text-xl p-2">Enter your age:</label> <input type="number" id="age" name="age" class="border rounded-lg p-4 w-24 mr-4" bind:value={age} /> <button on:click={() => showTicket = true} class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-full transition duration-300 ease-in-out transform hover:scale-105 hover:shadow-md ">Get Ticket</button> </div> {#if showTicket} {#if age > 0} {#if ticketPrice !== null} <div class=" bg-yellow-300 w-52 hover:bg-yellow-400 border-2 border-yellow-500 rounded-lg p-4 shadow-lg transform scale-105 transition duration-300 ease-in-out "> <p class="text-2xl font-bold mb-2">Ticket Details</p> <p class="text-blue-500">Name: {name}</p> <p class="text-blue-500">Date: {new Date().toLocaleDateString()}</p> <p class="text-green-600">Ticket Price: ${calculateTicketPrice()}</p> <p class="text-purple-500 mt-2 hover:text-purple-700 cursor-pointer transition duration-300 ease-in-out">Enjoy the ride!</p> </div> {:else} <p class="text-red-500 text-xl mt-4">Sorry, you are not allowed to enter the fun ride.</p> {/if} {/if} {/if} </div>
In this example, we calculate the ticket price based on the
age
variable using conditional statements. If the age falls within one of the specified ranges, it displays the ticket price; otherwise, it informs the user that they are not allowed to enter the fun ride.Conditional rendering in Svelte makes it easy to create dynamic and responsive interfaces, like our ticket pricing system for the fun ride.๐ข๐
Rendering Lists in Svelte
Now, let's see another aspect of Svelte: rendering lists using the {#each}
block.
Using {#each}
to Render Lists
Svelte provides a convenient way to iterate over arrays and render lists of elements using the {#each}
block. Here's an example:
<script>
let fruits = ['Apple', 'Banana', 'Cherry'];
</script>
<ul class="list-disc pl-4">
{#each fruits as fruit }
<li class="text-green-600">{fruit}</li>
{/each}
</ul>
In this code:
We have an array of
fruits
.We use
{#each}
to iterate over thefruits
array and render a list item (<li>
) for each fruit.We also display the index of each fruit in the array.
Using Keys in Lists
When rendering lists in Svelte, it's crucial to understand the significance of using keys. Keys are unique identifiers assigned to each item in the list, helping Svelte efficiently update and manipulate the DOM when the list changes.
Why Use Keys?
Imagine you have a list of items displayed on a web page. This list can change dynamically due to various actions, such as adding or removing items. When a change occurs, Svelte needs to update the DOM to reflect the new state of the list.
Without keys, Svelte might struggle to differentiate between items in the old list and items in the new list. This can lead to unnecessary re-rendering of elements, affecting performance and potentially causing unintended side effects.
Let's illustrate the importance of keys with an example:
<script> let fruits = ['Apple', 'Banana', 'Cherry']; </script> <ul class="list-disc pl-4"> {#each fruits as fruit (fruitIndex)} <li class="text-green-600">{fruit} (Index: {fruitIndex})</li> {/each} </ul>
In this code, we have a list of fruits. Each item in the list is rendered as an
<li>
element within an unordered list. The index of each fruit is also displayed.Now, let's say we want to add a new fruit to our list:
<script> let fruits = ['Apple', 'Banana', 'Cherry', 'Date']; </script>
Without keys, when Svelte updates the list, it might re-render all elements, even though the existing items haven't changed. This inefficiency can lead to performance issues, especially with larger lists.
By using keys, we provide Svelte with a unique identifier for each item. When we add the 'Date' fruit with a key, Svelte knows precisely which item has been added and can efficiently update the DOM without affecting other elements.
Now a note - [Svelte's reactivity system ensures that when you add or remove elements from an array, your UI stays in sync with the data, providing a seamless and responsive user experience.]
example :
Adding and Removing Elements of an Array
<script>
let products = [
{ id: 1, name: 'Product A', price: 10 },
{ id: 2, name: 'Product B', price: 20 },
{ id: 3, name: 'Product C', price: 30 }
];
let newProduct = {
id: null,
name: '',
price: 0
};
function addProduct() {
if (newProduct.name && newProduct.price > 0) {
newProduct.id = products.length + 1;
products = [...products, { ...newProduct }];
newProduct = {
id: null,
name: '',
price: 0
};
}
}
function removeProduct(id) {
products = products.filter(product => product.id !== id);
}
</script>
<div class="mx-auto p-4">
<input type="text" bind:value={newProduct.name} placeholder="Product Name" class="border rounded-lg p-2" />
<input type="number" bind:value={newProduct.price} placeholder="Price" class="border rounded-lg p-2" />
<button on:click={addProduct} class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-full transition duration-300 ease-in-out transform hover:scale-105 hover:shadow-md">Add Product</button>
</div>
<ul class="mt-4">
{#each products as product (product.id)}
<li key={product.id} class="bg-yellow-100 p-4 mb-2 rounded-lg shadow-md flex justify-between items-center">
<div>
<p class="text-xl font-semibold">{product.name}</p>
<p class="text-gray-600">${product.price}</p>
</div>
<button on:click={() => removeProduct(product.id)} class="bg-red-500 hover:bg-red-600 text-white py-2 px-4 rounded-full transition duration-300 ease-in-out transform hover:scale-105 hover:shadow-md">Remove</button>
</li>
{/each}
/ul>
We've laid the foundation of Svelte's basics, but this is just the beginning. The world of Svelte is full of possibilities waiting to be explored.
For the assignment, take the fun ride we built earlier and expand it. Add more exciting rides using lists and create separate tickets for each ride. This will not only solidify your understanding but also enhance your web development skills.
Remember, learning is a journey. If you face any challenges or need clarification, don't hesitate to reach out via email or comments. Your path to mastering Svelte has just begun, and the adventures ahead are limitless! ๐ข๐.
Thank youโค๏ธ
Subscribe to my newsletter
Read articles from Joel Jaison directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Joel Jaison
Joel Jaison
I am a third-year computer science student studying at Sahrdaya College of Engineering in Kodakara, with a passion for web development and open-source contributions. My expertise lies in full-stack web development using the MERN stack, with proficiency in building scalable and responsive web applications. Apart from web development, I also have a strong foundation in data structures and algorithms, which has enabled me to participate in numerous online coding contests and events. I am constantly seeking opportunities to challenge myself and improve my skills, whether it's through personal projects or collaboration with other developers. Currently, I am focusing on making meaningful contributions to open-source projects, leveraging my skills to solve real-world problems and make a positive impact on the community. I believe that technology has the power to change lives, and I am committed to using my abilities to create innovative solutions that make a difference.