Belajar SvelteKit - Reactive UI & Components
Episode 6 of 24

Belajar SvelteKit - Reactive UI & Components

Episode ini membahas sisi presentasi SvelteKit: dasar-dasar komponen Svelte dengan runes, reactive statements dan bindings, slot serta context module untuk komponen reusable, dan styling scoped dengan CSS global. Kalian akan membangun UI yang benar-benar reaktif terhadap perubahan state.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Data sudah mengalir dari server ke halaman lewat load functions. Sekarang kita berbicara tentang bagaimana data itu ditampilkan dan bagaimana UI merespons interaksi pengguna. Episode 6 adalah jantung dari pengalaman Svelte: komponen, reaktivitas, dan styling.

Svelte 5 memperkenalkan runes sebagai cara baru menulis reaktivitas. Konsepnya lebih eksplisit daripada versi lama dan membuat mental model lebih sederhana: state yang dideklarasikan dengan $state otomatis memicu pembaruan UI saat berubah, tanpa virtual DOM.

Setelah episode ini, kalian bisa memecah aplikasi menjadi komponen-komponen kecil yang reusable, berbagi data antar komponen dengan slot dan context, serta mengontrol scope styling dengan tepat.

Svelte Component Basics

Props dengan $props

Setiap komponen Svelte adalah file .svelte yang berisi script, markup, dan style. Data yang masuk dari parent dideklarasikan dengan rune $props.

Komponen dengan props
<script>
    let { nama, jumlah = 0 } = $props();
    let nilai = $state(0);
 
    function tambah() {
        nilai += 1;
    }
</script>
 
<h1>Halo, {nama}</h1>
<p>Nilai internal: {nilai}</p>
<p>Jumlah dari props: {jumlah}</p>
<button onclick={tambah}>Tambah</button>

Rune $props() mendefinisikan prop yang diterima komponen, lengkap dengan nilai default. Deklarasi destructuring ini membuat API komponen mudah dibaca.

State dengan $state

Rune $state membuat variabel menjadi reactive. Setiap kali nilainya diubah, komponen otomatis di-render ulang. Tidak perlu memanggil setter atau fungsi khusus — penugasan biasa sudah cukup.

Reaktivitas Svelte terjadi di level compiler: kode diubah menjadi update yang presisi. Ini berbeda dengan virtual DOM yang menghitung diff di runtime, dan inilah yang membuat Svelte sangat ringan di client.

Reactive Statements dan Bindings

Derived dengan $derived

Saat sebuah nilai dihitung dari state lain dan harus selalu sinkron, gunakan $derived. Nilai derived dihitung ulang hanya ketika dependensinya berubah.

Derived dan two-way binding
<script>
    let harga = $state(1000);
    let jumlah = $state(2);
    let total = $derived(harga * jumlah);
</script>
 
<input type="range" bind:value={harga} min="100" max="10000" step="100" />
<input type="number" bind:value={jumlah} min="1" />
 
<p>Total: Rp {total.toLocaleString("id-ID")}</p>

Directive bind:value menciptakan two-way binding: perubahan dari input menulis ke state, dan perubahan state menulis ke input. Svelte menyediakan banyak binding: bind:value untuk input, bind:checked untuk checkbox, bind:this untuk referensi elemen, dan bind:group untuk grup radio.

Efek Samping dengan $effect

Untuk menjalankan kode setiap kali state berubah, misalnya menyimpan preferensi ke localStorage, gunakan $effect. Bedakan dengan $derived: derived untuk menghitung nilai murni, effect untuk aksi sampingan. Gunakan effect dengan hemat karena ia berjalan setiap dependensi berubah.

Slot dan Context Module

Children dan Named Slots

Komponen reusable menerima konten dari parent lewat slot. Di Svelte 5, konten dibawa sebagai prop children yang dirender dengan {@render children()}.

Komponen kartu dengan slot
<script>
    let { children, judul } = $props();
</script>
 
<article class="kartu">
    <h2>{judul}</h2>
    {@render children()}
</article>
 
<style>
    .kartu {
        border: 1px solid #e2e8f0;
        border-radius: 8px;
        padding: 1rem;
    }
</style>

Dengan prop children, komponen seperti kartu, modal, atau panel bisa dibungkus konten bebas. Untuk konten bernama, deklarasikan prop dengan key string dan render sesuai kebutuhan.

Context Module dan setContext

Blok script module dijalankan satu kali per aplikasi, bukan per instance komponen. Cocok untuk konstanta dan helper yang tidak bergantung pada state instance.

Untuk berbagi data antar komponen tanpa menurunkannya berlapis-lapis, gunakan setContext dan getContext dari modul svelte. Context terikat pada pohon komponen, jadi nilai yang sama dibagikan ke seluruh turunan tetapi terisolasi per instance parent.

Styling Scoped dan Global CSS

Styling Scoped

Style di dalam <style> komponen bersifat scoped: Svelte menambahkan class unik pada elemen dan selector. Ini mencegah tabrakan antar komponen dan membuat kode CSS mudah dilacak. Selector anak seperti .kartu p tetap bekerja karena kompiler menambahkan class scope pada elemen yang relevan.

CSS Global dan :global

Untuk menimpa scope, gunakan :global(...). Selektor ini menargetkan elemen apa pun di halaman tanpa class scope. Gunakan secara hati-hati dan terbatas, misalnya untuk style dari library eksternal atau reset yang memang harus menyentuh semua elemen.

CSSCSS global di komponen
<style>
    :global(body) {
        font-family: "Inter", system-ui, sans-serif;
        margin: 0;
    }
 
    .kartu {
        background: var(--surface);
    }
</style>

Variabel CSS

Variabel CSS --nama menembus boundary komponen dan bisa dipakai bersama sistem design. Gabungkan variabel CSS dengan scoped style untuk membuat tema yang fleksibel tanpa melepas kontrol scope.

Penutup

Inti yang harus dibawa pulang:

  • Komponen Svelte terdiri atas script, markup, dan style dalam satu file .svelte.
  • Rune $props untuk input komponen, $state untuk state reactive, $derived untuk nilai turunan, dan $effect untuk efek samping.
  • Two-way binding dengan bind:value dan varian lainnya membuat form dan interaksi jadi ringkas.
  • Slot (children) dan named slots memungkinkan komponen reusable yang menerima konten bebas.
  • setContext dan getContext membagikan data di dalam pohon komponen; script module untuk kode satu kali.
  • Styling Svelte scoped secara default; :global() menembus scope untuk kasus khusus.

Di episode 7 selanjutnya kita memperdalam state management: stores & state management. Kalian akan mempelajari writable, readable, dan derived stores, custom stores untuk shared state, sinkronisasi state antara server dan client, serta integrasi dengan TanStack Query.

Belajar SvelteKit - Reactive UI & Components | Belajar SvelteKit