Reactive State

Loading concept...

🎭 Svelte Reactivity: The Magic Notebook

The Story of the Magic Notebook 📔

Imagine you have a magic notebook. When you write a number on one page, other pages that depend on that number automatically update themselves. You don’t have to erase and rewrite—the notebook does it for you!

That’s exactly what Svelte’s reactivity system does for your code.


🌟 Chapter 1: Declaring Variables (The Old Way)

Before we discover the magic, let’s see the ordinary way to store information.

What is a Variable?

Think of a variable like a labeled box. You put something inside, and the label tells you what’s in it.

let name = "Alex";
let age = 10;
let favoriteColor = "blue";

Simple Example:

  • name is a box labeled “name” with “Alex” inside
  • age is a box labeled “age” with 10 inside
  • You can change what’s inside anytime!
age = 11;  // Happy Birthday! 🎂

The Problem: In regular JavaScript, if something else depends on age, it won’t know the box changed. You’d have to manually tell everything to update.


✨ Chapter 2: The $state Rune (Your Magic Wand)

What is a Rune?

A rune is like a magic spell word. In Svelte 5, runes start with $ and give your variables superpowers!

The $state Rune

$state turns an ordinary box into a magic box that tells everyone when something changes!

<script>
  let count = $state(0);
</script>

<button onclick={() => count++}>
  Clicked {count} times
</button>

What happens:

  1. count starts at 0
  2. When you click, count becomes 1
  3. The screen automatically shows “Clicked 1 times”
  4. No manual updates needed! ✨

Before vs After

Without $state With $state
let count = 0 let count = $state(0)
Screen stays frozen Screen updates automatically
You do all the work Svelte does the work for you

🧊 Chapter 3: $state.raw (The Frozen Box)

When You Don’t Need Magic

Sometimes you have big data that doesn’t need to update piece by piece. It only changes all at once.

Think of it like a frozen pizza 🍕—you don’t change one topping at a time. You swap the whole pizza!

<script>
  let bigData = $state.raw([
    { id: 1, name: "Item 1" },
    { id: 2, name: "Item 2" }
  ]);

  function replaceAll() {
    // Swap the entire list
    bigData = [
      { id: 3, name: "New Item" }
    ];
  }
</script>

When to use $state.raw:

  • ✅ Large lists that replace entirely
  • ✅ Data from a server (arrives complete)
  • ❌ Not for data you edit piece by piece

Why use it? It’s faster because Svelte doesn’t watch every tiny piece.


📚 Chapter 4: Reactive Arrays (Magic Lists)

Arrays are like lists of things. With $state, your lists become magic lists!

Creating a Reactive Array

<script>
  let fruits = $state(["apple", "banana"]);
</script>

<ul>
  {#each fruits as fruit}
    <li>{fruit}</li>
  {/each}
</ul>

<button onclick={() => fruits.push("orange")}>
  Add Orange 🍊
</button>

What happens when you click:

  1. “orange” gets added to the list
  2. Screen instantly shows the new fruit
  3. Magic! 🪄

Array Methods That Work

fruits.push("grape");    // Add to end
fruits.pop();            // Remove last
fruits.shift();          // Remove first
fruits[0] = "mango";     // Replace first

All these trigger updates automatically!


🏠 Chapter 5: Reactive Objects (Magic Folders)

Objects are like folders with labeled pockets. Each pocket has a name and holds something.

Creating a Reactive Object

<script>
  let person = $state({
    name: "Sam",
    age: 8,
    hobby: "drawing"
  });
</script>

<p>Name: {person.name}</p>
<p>Age: {person.age}</p>

<button onclick={() => person.age++}>
  Birthday! 🎂
</button>

What happens:

  • Click the button
  • person.age goes from 8 to 9
  • The screen updates instantly!

Adding New Pockets

person.favoriteFood = "pizza";
// Screen updates to show the new info!

🌊 Chapter 6: Deep Reactivity (Magic All the Way Down)

What is Deep Reactivity?

Imagine a Russian nesting doll 🪆. There’s a doll inside a doll inside a doll.

Deep reactivity means Svelte’s magic works at EVERY level—even the smallest doll inside!

<script>
  let school = $state({
    name: "Sunny School",
    classes: [
      {
        name: "Art",
        students: ["Amy", "Bob"]
      }
    ]
  });
</script>

<p>First class: {school.classes[0].name}</p>

<button onclick={() => {
  school.classes[0].students.push("Charlie");
}}>
  Add Student
</button>

The magic reaches:

  • school
  • school.classes
  • school.classes[0]
  • school.classes[0].students

Every level updates the screen when changed!

graph TD A[school] --> B[name: Sunny School] A --> C[classes] C --> D[Class 0] D --> E[name: Art] D --> F[students] F --> G[Amy] F --> H[Bob] F --> I[Charlie ✨ new!]

🔮 Chapter 7: The $derived Rune (Automatic Calculations)

The Magic Calculator

What if one value depends on another? Like:

“My birth year = Current year - My age”

With $derived, Svelte calculates it automatically whenever the source changes!

<script>
  let price = $state(100);
  let quantity = $state(2);

  let total = $derived(price * quantity);
</script>

<p>Price: ${price}</p>
<p>Quantity: {quantity}</p>
<p>Total: ${total}</p>

<button onclick={() => quantity++}>
  Add One More
</button>

What happens:

  1. Start: price=100, quantity=2, total=200
  2. Click button: quantity becomes 3
  3. total automatically becomes 300!

Key Rules

Rule Explanation
Read-only You can’t set total = 500 directly
Auto-updates Changes when source values change
Simple formula Best for one-line calculations

🧙‍♂️ Chapter 8: The $derived.by Rune (Complex Magic)

When Simple Isn’t Enough

Sometimes your calculation needs multiple steps. That’s when $derived.by comes in!

Think of it like a recipe 📝—you need several steps to make the final dish.

<script>
  let items = $state([
    { name: "Apple", price: 2 },
    { name: "Bread", price: 3 },
    { name: "Milk", price: 4 }
  ]);

  let summary = $derived.by(() => {
    let total = 0;
    let count = items.length;

    for (let item of items) {
      total += item.price;
    }

    return {
      itemCount: count,
      totalPrice: total,
      average: total / count
    };
  });
</script>

<p>Items: {summary.itemCount}</p>
<p>Total: ${summary.totalPrice}</p>
<p>Average: ${summary.average.toFixed(2)}</p>

$derived vs $derived.by

$derived $derived.by
One-line formula Multi-step logic
$derived(a + b) $derived.by(() => { ... })
Quick calculations Complex transformations
// Simple: use $derived
let doubled = $derived(count * 2);

// Complex: use $derived.by
let stats = $derived.by(() => {
  // Step 1: Filter
  let valid = items.filter(i => i.active);
  // Step 2: Calculate
  let sum = valid.reduce((a, b) => a + b.value, 0);
  // Step 3: Return result
  return { count: valid.length, sum };
});

🎯 The Complete Picture

graph TD A[$state] --> B[Basic reactive value] A --> C[$state.raw] C --> D[Fast, replace-only] E[$derived] --> F[Auto-calculated value] E --> G[$derived.by] G --> H[Complex calculations] B --> I[Arrays] B --> J[Objects] I --> K[Deep Reactivity] J --> K

🌈 Summary: Your Reactivity Toolkit

Tool When to Use Example
$state(value) Any reactive data let count = $state(0)
$state.raw(value) Big data, full replacement let data = $state.raw([...])
$derived(expr) Simple calculations let double = $derived(n * 2)
$derived.by(fn) Complex logic let result = $derived.by(() => {...})

🚀 You Did It!

You now understand Svelte’s reactivity system! Remember:

  1. $state makes values reactive
  2. $state.raw is for big, swap-all-at-once data
  3. Arrays and Objects inside $state are deeply reactive
  4. $derived calculates values automatically
  5. $derived.by handles complex multi-step calculations

Like a magic notebook, your Svelte app now updates itself whenever something changes. No manual work needed! ✨

Loading story...

No Story Available

This concept doesn't have a story yet.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Interactive Preview

Interactive - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Interactive Content

This concept doesn't have interactive content yet.

Cheatsheet Preview

Cheatsheet - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Cheatsheet Available

This concept doesn't have a cheatsheet yet.

Quiz Preview

Quiz - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Quiz Available

This concept doesn't have a quiz yet.