2020-04-10

Svelte Tutorial 2: Reactivity (English & Indonesia)

English


Reactivity is the ability of the system in svelte to keep DOM in sync with application state. Svelte automatically update DOM/invalidate state if there's an assignment operator. Below is explanation of reactivity in Svelte:

Assignment


For example when you have function handleClick like this:

<script>
 let count = 0;

 function handleClick() {
  count += 1;
 }
</script>

<button on:click={handleClick}>
   Clicked {count} {count === 1 ? 'time' : 'times'}
</button>


that is called everytime there is a click on the button, when handleClick assign new value to variable count the text on the button get updated automatically, so it will represent new value of count.

Declaration


When you want to have variable that respond to change of state happen within your app, use reactive declaration like this:

<script>
 let count = 0;
 $: doubled = count * 2;      // reactive declaration
 function handleClick() {

  count += 1;
 }

</script>

<button on:click={handleClick}>
 Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

<p>{count} doubled is {doubled}</p>


Notice the $: sign before declaring doubled, so when count variable gets updated doubled also changed to represent new value.

Statement


You can also use reactive declaration for any statement, for example, we can log the value of count whenever it changes:

$: console.log(`the count is ${count}`);

you can also grouped several statement together:

$: {
 console.log(`the count is ${count}`);
 alert(`I SAID THE COUNT IS ${count}`);
}


you can even use reactivity for if statement:

<script>
 let count = 0;
 $: if (count >= 10) {
  alert(`count is dangerously high!`);
  count = 9;
 }
 function handleClick() {
  count += 1;
 }
</script>
<button on:click={handleClick}>
 Clicked {count} {count === 1 ? 'time' : 'times'}
</button>


Notice the $: sign before every statement or block of statement, if you are not using this, then your statement wont be reactive and wont be executed as the value of variable changed.

Updating array or object


Because in svelte reactivity is triggered by assignment, if you use array method like push, new state wont be updated. So you will have to add another line that seem redundant but since it does assignment, it will trigger reactivity

numbers.push(numbers.length + 1);  // no assignment = not reactive
numbers = numbers                  // has assignment = reactive


you can also use something like this  (will be reactive)

numbers = [...numbers, numbers.length + 1];

Assignments to properties of arrays and objects — e.g.
obj.foo += 1 or array[i] = x , work the same way as assignments to the values themselves (will be reactive). A simple rule of thumb: the name of the updated variable must appear on the left hand side of the assignment. This example below won't update references to obj.foo.bar, unless you follow it up with obj = obj.

const foo = obj.foo;
foo.bar = 'baz';







Indonesia


Reactivity adalah kemampuan sistem svelte untuk mejaga DOM tetap sama dengan keadaan aplikasi. Svelte akan meng update DOM/invalidate state secara otomatis apabila ada operasi perubahan/pengisian nilai ke dalam variabel menggunakan operator assignment (=). Berikut di bawah ini adalah penjelasan reactivity dalam svelte:

Assignment


Sebagai contoh ketika kita mempunyai fungsi handleClick seperti ini:

<script>
 let count = 0;

 function handleClick() {
  count += 1;
 }
</script>

<button on:click={handleClick}>
   Clicked {count} {count === 1 ? 'time' : 'times'}
</button>


yang akan dipanggil setiap kali ada klik pada button, maka ketika handleClick mengisi  nilai yang baru ke variable count, tulisan pada tombol akan terupdate secara otomatis, menyesuaikan dengan nilai yang baru count.

Declaration


Ketika kita ingin mempunya variabel yang merespon perubahan nilai yang terjadi di aplikasi, gunakan deklarasi reactive seperti ini:

<script>
 let count = 0;
 $: doubled = count * 2;      // deklarasi reactive
 function handleClick() {

  count += 1;
 }

</script>

<button on:click={handleClick}>
 Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

<p>{count} doubled is {doubled}</p>


Perhatikan tanda $: sebelum deklarasi variabel doubled, maka ketika variabel count dirubah nilainya, variabel doubled juga akan berubah menyesuaikan dengan nilai baru yang semestinya.

Statement


Kita juga bisa menggunakan deklarasi reactive untuk kalimat apapun, sebagai contoh, kita bisa memasukkan perubahan nilai count ke dalam log:

$: console.log(`the count is ${count}`);

bisa juga mengelompokkan beberapa baris:

$: {
 console.log(`the count is ${count}`);
 alert(`I SAID THE COUNT IS ${count}`);
}


bahkan bisa digunakan untuk kalimat if

<script>
 let count = 0;
 $: if (count >= 10) {
  alert(`count is dangerously high!`);
  count = 9;
 }
 function handleClick() {
  count += 1;
 }
</script>
<button on:click={handleClick}>
 Clicked {count} {count === 1 ? 'time' : 'times'}
</button>


Perhatikan tanda $: sebelum semua kalimat atau kelompok kalimat, jika lupa menambahkan tanda ini maka kalimat itu tidak akan reactive dan tidak akan dieksekusi biarpun ada perubahan nilai pada variabel.

Updating array or object


Karena di svelte reactivity dipicu oleh assignment (tanda =) , jika kita menggunakan method array seperti push, maka reactivity tidak akan berjalan. Maka untuk memancing supaya reactive, kita bisa menambahkan baris (yang terlihat redundant) seperti di bawah ini:

numbers.push(numbers.length + 1);  // no assignment = not reactive
numbers = numbers                  // has assignment = reactive


Kita juga bisa menggunakan penambahan array seperti di bawah ini (akan reactive):

numbers = [...numbers, numbers.length + 1];

Assignment pada properti objek atau array — seperti ini:
obj.foo += 1 atau array[i] = x , akan menghasilkan sesuatu yang sama dengan jika melakukan assignment pada nilai variabel langsung (jadi akan reactive). Aturan sederhana yang bisa kita pegang adalah jika nama dari variabel yang diubah nilai nya ada di sebelah kiri operator assignment (tanda =) maka akan memicu reactivity.
Contoh di bawah ini tidak akan mengubah nilai pada obj.foo.bar, karena obj.foo ada di sebelah kanan, kecuali kita menambahkan obj = obj untuk memancing reactivity

const foo = obj.foo;
foo.bar = 'baz';