ข้ามไปยังเนื้อหา

Built-in Stores

writable(initial) จาก svelte/store สร้าง store ที่คุณอ่าน และ เขียนได้ มีสาม method: set(value) (แทนที่), update(fn) (เปลี่ยนจากค่าปัจจุบัน) และ subscribe(fn) (contract)

stores/count.js
import { writable } from 'svelte/store';
export const count = writable(0);
<script>
import { count } from './stores/count.js';
</script>
<button onclick={() => count.update((n) => n + 1)}>increment</button>
<button onclick={() => count.set(0)}>reset</button>
<p>{$count}</p> <!-- $ reads the value and re-renders -->

ทุกคอมโพเนนต์ที่ import count จะ share store ตัวเดียวกัน — เขียนที่จุดหนึ่งก็อัปเดตทุกที่ที่ถูกอ่าน นั่นคือ shared state ในบรรทัดเดียว

readable(initial, start) สร้าง store ที่ค่าถูกควบคุมโดย start function ไม่ใช่โดยผู้ใช้ start function รับ set (และ update) ทำงานเมื่อ subscriber ตัวแรกมาถึง และ return ฟังก์ชัน stop ที่ทำงานเมื่อ subscriber ตัวสุดท้ายจากไป — เหมาะกับการห่อ source แบบ push

// stores/time.js — a clock nobody can set from outside
import { readable } from 'svelte/store';
export const time = readable(new Date(), (set) => {
const id = setInterval(() => set(new Date()), 1000);
return () => clearInterval(id); // cleanup when no one is listening
});

lifecycle แบบ start/stop หมายความว่า interval ทำงานเฉพาะตอนที่มีบางอย่าง subscribe อยู่จริง — ไม่มีงานเสียเปล่า

derived(source, fn) สร้าง store ใหม่จาก store ที่มีอยู่หนึ่งตัวหรือมากกว่า โดยคำนวณใหม่เมื่อ source ใด ๆ เปลี่ยน

import { derived } from 'svelte/store';
import { count } from './count.js';
export const doubled = derived(count, ($count) => $count * 2);
// From multiple stores — pass an array:
export const summary = derived(
[count, doubled],
([$count, $doubled]) => `${$count} doubled is ${$doubled}`
);
flowchart LR
  w["writable: set, update, subscribe"] --> use["อ่านด้วย $ ในคอมโพเนนต์"]
  r["readable: start/stop ควบคุมค่า"] --> use
  d["derived: คำนวณจาก store อื่น"] --> use
built-in store ทั้งสาม

เมื่อมี runes ให้ใช้แล้ว ให้เลือก stores เมื่อคุณต้องการ contract โดยเฉพาะ: การห่อ external push source (readable รอบ WebSocket), การ interop กับ observable หรือการทำงานใน code ที่ใช้ store อยู่แล้ว สำหรับ app state ธรรมดาที่ share ข้ามคอมโพเนนต์ runed module (บทถัดไป) มักจะง่ายกว่า

`writable` store มีสาม method อะไรบ้าง?
อะไรพิเศษเกี่ยวกับ start function ของ `readable` store?
`derived(count, $count => $count * 2)` สร้างอะไร?
เมื่อไรที่ยังควรเลือก store แทน runes?