The Store Contract
store คือแค่ contract
หัวข้อที่มีชื่อว่า “store คือแค่ contract”Svelte store ไม่มีอะไร magic เลย store คือ object ใด ๆ ที่มี method subscribe ที่รับ callback แล้วเรียก callback นั้นด้วยค่าปัจจุบัน ทั้งทันทีและทุกครั้งที่ค่าเปลี่ยน — โดย return ฟังก์ชัน unsubscribe กลับมา นั่นคือ contract ทั้งหมด:
// The minimal store contract, written by hand.function createCounter() { let value = 0; const subscribers = new Set();
return { subscribe(fn) { fn(value); // 1. call immediately with the current value subscribers.add(fn); return () => subscribers.delete(fn); // 2. return an unsubscribe function }, increment() { value += 1; subscribers.forEach((fn) => fn(value)); // 3. notify on change }, };}เพราะ contract เล็กขนาดนี้ อะไรก็ตาม ที่ทำตาม contract นี้ได้ก็เป็น store — รวมถึง RxJS observable (ที่ก็มี subscribe ที่เข้ากันได้) ความ interoperable นี้คือเหตุผลที่ Svelte นิยาม contract ไว้แทนที่จะเป็น class ตายตัว
prefix $ ทำ auto-subscribe ให้
หัวข้อที่มีชื่อว่า “prefix $ ทำ auto-subscribe ให้”การเขียน store.subscribe(...) เองในทุกคอมโพเนนต์คงน่าเบื่อและ leak ง่าย ในคอมโพเนนต์ Svelte ให้ shorthand $store: เติม $ หน้า store แล้ว Svelte จะ subscribe ให้ ให้ค่าปัจจุบัน re-render เมื่อค่าเปลี่ยน และ unsubscribe ให้อัตโนมัติ เมื่อคอมโพเนนต์ถูกทำลาย
<script> import { counter } from './counter.js';</script>
<!-- $counter is the current value; the component re-renders on every change --><button onclick={counter.increment}>count is {$counter}</button>flowchart LR prefix["$store ในคอมโพเนนต์"] --> sub["subscribe ตอน mount"] sub --> val["อ่านค่าปัจจุบัน"] val --> rerender["re-render เมื่อค่าเปลี่ยน"] rerender --> unsub["auto-unsubscribe ตอน destroy"]
คุณยัง assign ให้ $store ได้ด้วย ($counter = 5) ถ้า store เป็น writable — Svelte จะ compile เป็นการเรียก set ของ store prefix $ ใช้ได้เฉพาะในไฟล์ .svelte และ module .svelte.js/.svelte.ts เพราะเป็น compiler magic ไม่ใช่ฟังก์ชัน runtime
ทำไม contract ยังสำคัญใน Svelte 5
หัวข้อที่มีชื่อว่า “ทำไม contract ยังสำคัญใน Svelte 5”ถึงแม้ runes จะครอบคลุม shared-state ส่วนใหญ่แล้ว (บทถัด ๆ ไป) store contract ก็ยังมีค่า:
- interop source ใด ๆ ที่คล้าย observable และมี
subscribeที่เข้ากันได้ก็ใช้กับ$ได้ — RxJS, custom event stream, third-party library - async source
readable(บทถัดไป) ห่อ source แบบ push (WebSocket, geolocation watcher) ไว้หลัง contract ง่าย ๆ อันเดียวกัน - code เดิม Svelte หลายล้านบรรทัดใช้ stores การเข้าใจ contract ช่วยให้คุณอ่านและดูแล code เหล่านั้นได้