Lesson 5
Reactive Classes with Getters and Setters in Svelte
Introduction to Reactive Classes in Svelte

In the previous lesson, you learned how to use $effect to implement debouncing, a technique that helps manage frequent updates efficiently. Now, we’ll shift our focus to organizing state logic using reactive classes in Svelte. While $state and $effect are powerful tools for managing reactivity, classes with getters and setters can help you structure your code more cleanly, especially when dealing with complex state logic.

In Svelte, reactivity is achieved through runes like $state, which allow you to create reactive variables. However, as your application grows, managing these variables individually can become cumbersome. Classes provide a way to encapsulate related state and logic into a single unit, making your code easier to maintain and understand.

In this lesson, you’ll learn how to use classes with getters and setters to manage reactive state in Svelte. By the end, you’ll be able to build a Temperature Converter that converts between Celsius and Fahrenheit using a reactive class. This builds on your knowledge of $state and introduces a new way to structure your applications.

Let’s get started!

Understanding Getters and Setters

Before diving into reactive classes, let’s briefly review what getters and setters are in JavaScript. Getters and setters are special methods that allow you to control how a property is accessed or modified. A getter is used to retrieve the value of a property, while a setter is used to assign a value to it. This gives you the ability to add logic when getting or setting a property, such as validation or transformation.

For example, consider a simple class with a getter and setter:

JavaScript
1class Counter { 2 #count = 0; // Private field 3 4 get value() { 5 return this.#count; 6 } 7 8 set value(newValue) { 9 this.#count = Number(newValue); // Ensure numeric value 10 } 11}

In this example, the value property is controlled by a getter and setter. The getter returns the current value of #count, while the setter ensures that the new value is always a number. This pattern is particularly useful in Svelte when combined with reactive state.

Building a Temperature Converter

Now, let’s apply this knowledge to build a Temperature Converter in Svelte. The converter will allow users to input a temperature in Celsius or Fahrenheit, and it will automatically update the other value based on the input. We’ll use a reactive class to manage the state and logic for this conversion.

Here’s the complete code for the TemperatureConverter class:

svelte
1<script> 2 class TemperatureConverter { 3 #celsius = $state(0); // Private reactive state for Celsius 4 5 get celsius() { 6 return this.#celsius; 7 } 8 9 set celsius(newValue) { 10 this.#celsius = Number(newValue); // Ensure numeric value 11 } 12 13 get fahrenheit() { 14 return (this.#celsius * 9/5) + 32; // Computed value for Fahrenheit 15 } 16 17 set fahrenheit(newValue) { 18 this.#celsius = (Number(newValue) - 32) * 5/9; // Convert Fahrenheit to Celsius 19 } 20 } 21 22 const converter = new TemperatureConverter(); 23</script> 24 25<h3>Temperature Converter</h3> 26 27<label> 28 Celsius: 29 <input type="number" bind:value={converter.celsius} /> 30</label> 31 32<br /> 33 34<label> 35 Fahrenheit: 36 <input type="number" bind:value={converter.fahrenheit} /> 37</label> 38 39<p><strong>Current Values:</strong></p> 40<p>Celsius: {converter.celsius}</p> 41<p>Fahrenheit: {converter.fahrenheit}</p>

Let’s break this down step by step:

  1. Private Reactive State: The #celsius property is defined as a private reactive state using $state(0). This ensures that changes to #celsius trigger reactivity in Svelte.
  2. Getters and Setters: The celsius and fahrenheit properties are controlled by getters and setters. The getters return the current value, while the setters handle the conversion logic.
  3. Binding to UI: The bind:value directive connects the input fields to the celsius and fahrenheit properties, ensuring that the UI updates reactively.
  4. Displaying Values: The current values of celsius and fahrenheit are displayed in the UI using curly braces {}.

When you run this code, you’ll see two input fields for Celsius and Fahrenheit. As you type in one field, the other field will update automatically based on the conversion logic. For example, if you enter 100 in the Celsius field, the Fahrenheit field will display 212.

Binding Class Properties to UI Elements

In the previous section, we used the bind:value directive to connect the input fields to the celsius and fahrenheit properties of the TemperatureConverter class. This is a powerful feature of Svelte that allows you to bind UI elements directly to reactive state.

Here’s how it works:

  • The bind:value directive creates a two-way binding between the input field and the property. When the user types in the input field, the property is updated, and when the property changes, the input field is updated.
  • This ensures that the UI always reflects the current state of the application, and changes to the state are immediately visible in the UI.

For example, in the TemperatureConverter class, the celsius and fahrenheit properties are bound to their respective input fields. When the user types in the Celsius field, the celsius setter is called, which updates the #celsius state and triggers the fahrenheit getter to recompute its value. The same happens in reverse when the user types in the Fahrenheit field.

This seamless integration between reactive state and UI elements is one of the key strengths of Svelte, and using classes with getters and setters makes it even easier to manage complex state logic.

Key Takeaways and Preparing for Practice

In this lesson, you learned how to use reactive classes with getters and setters to manage state in Svelte. Here’s a quick recap of what we covered:

  1. Reactive Classes: Classes provide a way to encapsulate related state and logic, making your code cleaner and more maintainable.
  2. Getters and Setters: Getters and setters allow you to control how properties are accessed or modified, adding logic like validation or transformation.
  3. Binding to UI: The bind:value directive creates a two-way binding between UI elements and reactive properties, ensuring that the UI updates reactively.

In the practice exercises, you’ll:

  1. Build a reactive class to manage a counter with increment and decrement methods.
  2. Experiment with adding validation logic to a setter.
  3. Apply reactive classes to other real-world scenarios.

Take your time to explore and experiment with the code. Reactive classes are a powerful tool that can help you structure your applications more effectively. Great job, and 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.