Runes vs Stores
counter ตัวเดียวกัน สองวิธี
หัวข้อที่มีชื่อว่า “counter ตัวเดียวกัน สองวิธี”ก่อน Svelte 5 การ share reactive state ข้ามคอมโพเนนต์หมายถึง store ตอนนี้คุณเอา $state ไปไว้ใน module แล้ว export ได้ runes ทำงานนอกคอมโพเนนต์ได้ — แต่เฉพาะในไฟล์นามสกุล .svelte.js หรือ .svelte.ts ซึ่งบอก compiler ให้เปิดการประมวลผล rune
เวอร์ชัน store:
import { writable } from 'svelte/store';export const count = writable(0);<script> import { count } from './counter.js';</script><button onclick={() => count.update((n) => n + 1)}>{$count}</button>เวอร์ชัน runes:
// counter.svelte.js ← note the .svelte.js extensionexport const counter = $state({ value: 0 });<script> import { counter } from './counter.svelte.js';</script><button onclick={() => counter.value++}>{counter.value}</button>ไม่มี writable ไม่มี set/update ไม่มี prefix $ — คุณอ่านและ mutate counter.value เหมือน object ธรรมดา และ reactive ทุกที่ที่ใช้
ทำไมต้อง export object ไม่ใช่ค่าเปล่า ๆ
หัวข้อที่มีชื่อว่า “ทำไมต้อง export object ไม่ใช่ค่าเปล่า ๆ”สังเกตว่าเวอร์ชัน runes export { value: 0 } ไม่ใช่ 0 การ export let x = $state(0) เปล่า ๆ จะคง link ข้าม module boundary ไว้ไม่ได้ — การ import จะ copy ค่าและเสีย reactivity ไป การ export object (หรือฟังก์ชันที่ return reactive state) ทำให้ทุกคนยังชี้ไปที่ reactive proxy ตัวเดียวกัน ดังนั้น mutation ที่ counter.value จึงกระจายไป นี่คือ gotcha ข้อเดียวของ module-level runes
เทียบกันข้าง ๆ
หัวข้อที่มีชื่อว่า “เทียบกันข้าง ๆ”Store (writable) | Runes (.svelte.js) | |
|---|---|---|
| อ่านในคอมโพเนนต์ | $count | counter.value |
| อัปเดต | count.set(x) / count.update(fn) | counter.value = x |
| นอกคอมโพเนนต์ | ใช้ได้ทุกที่ | ต้องใช้ .svelte.js/.svelte.ts |
| subscribe contract | มี (interop, observable) | ไม่มี |
| พิธีการ | มากกว่า (method, $) | น้อยกว่า (อ่าน/เขียนตรง ๆ) |
flowchart TB q["share reactive state ไหม"] --> interop["ต้องการ subscribe contract ไหม (observable, external push source)"] interop --> yes["ใช่: ใช้ store"] interop --> no["ไม่: export state จาก .svelte.js module"]
เมื่อไรควรใช้อะไร
หัวข้อที่มีชื่อว่า “เมื่อไรควรใช้อะไร”- runes (default) app state ที่ share ส่วนใหญ่ — cart, theme, current-user object ง่ายกว่า boilerplate น้อยกว่า และ mental model เดียวกับ component-local state
- stores เมื่อคุณต้องการ contract: ห่อ WebSocket หรือ push source อื่นด้วย
readable, interop กับ observable แบบ RxJS หรือดูแล code ที่ใช้ store อยู่แล้ว stores ไม่ใช่ของเก่า — แต่เป็นเครื่องมือเฉพาะทาง