Web/JavaScript

[Svelte] Reactivity

llHoYall 2021. 11. 25. 23:00

Reactivity is that other data or screens are automatically updated depending on the data change.

Reactive Assignments

This is a simple example of a reactive assignment.

Normal Variable

The screen is automatically updated since the data is updated.

<script lang="ts">
  let name = "HoYa";

  function changeName() {
    name = 'Kim';
  }
</script>

<div>Name: {name}</div>
<button on:click={changeName}>Change Name</button>

If we click the button, the value of the name variable is changed and displayed the changed value.

Array Variable

Now, let's do it again to the array variable.

<script lang="ts">
  let fruits = ['Apple', 'Banana', 'Cherry'];

  function changeFruits() {
    fruits.push('Dates');
  }
</script>

<h1>Fruits: {fruits}</h1>
<button on:click={changeFruits}>Change Fruits</button>

It doesn't work this time.

What's happening?

Svelte's reactivity works only with assignments

function changeFruits() {
  fruits.push('Dates');
  fruits = fruits;
}

Now, it works!

Object Variable

Now, it's the object variable time.

<script lang="ts">
  let user = {
    name: 'HoYa',
    appearance: {
      height: 178
    },
    hobby: ['reading', 'programming']
  };

  function changeUser() {
    user.name = 'Kim';
    user.appearance.height = 187;
    user.hobby.push('gaming');
  }
</script>

<h1>User: {user.name}, {user.appearance.height}, {user.hobby}</h1>
<button on:click={changeUser}>Change User</button>

user variable can have reactivity via $$invalidate() if we use it directly.

In other words, these codes don't have reactivity.

function changeUser() {
  user.hobby.push('gaming');
}

// or

function changeUser() {
  let appearance = user.appearance;
  appearance.height = 187;
}

The important thing is that in order for an object variable to be reactive, it should be reassigned.

Reactive Statements

Svelte's reactive statements are similar to the calculated property or computed property of other languages, and syntactically uses JavaScript's label statements.

<script lang="ts">
  let count = 0;

  $: doubled = count * 2;

  function increaseCount() {
    count++;
  }
</script>

<h1>Count: {count}, Doubled: {doubled}</h1>
<button on:click={increaseCount}>Increase Count</button>

Svelte's reactive statements use $: syntax.

It watches variables inside itself and automatically reacts to changes in values to perform the corresponding expression.

Note that, it is executed automatically once at first.

Reactivity Recipes

Let's take a look at some recipes of reactivity.

with Function Call

let count = 0;

$: count, log();
$: count,
  (() => {
    console.log('IIFE is called');
  })();

function log() {
  console.log('Log is called');
}

This is some kind of trick.

Actually, the count variable wasn't used. But, Svelte can detect the change of the variable and call the function each time.

with if Statement

$: if (count > 3) {
  console.log('Count is greater than 3');
}

with for Loop

$: for (let i = 0; i < 3; i += 1) {
  count;
  console.log(`For: ${i}`);
}

with switch Statement

$: switch (count) {
  case 7:
    console.log('Got Lucky');
    break;
  default:
    console.log('Waiting...');
}