Mental Shift จาก React สู่ Svelte
โมเดลความคิดของ React ถูกสร้างขึ้นบน immutability และ explicit setters คุณเรียก useState เพื่อรับ value และ setter แล้วต้องเรียก setter ทุกครั้งที่ต้องการอัปเดต Svelte 5 พลิกแนวคิดนี้ทั้งหมด — การกำหนดค่าคือ reactivity เขียน count++ แล้ว DOM จะอัปเดตเอง ไม่ต้องมี setter ไม่ต้องมี dispatch ไม่ต้องมีพิธีกรรมใดๆ
นี่คือการเปลี่ยนแปลงที่ใหญ่ที่สุดเพียงหนึ่งเดียวเมื่อย้ายจาก React ไปสู่ Svelte
แนวคิดหลัก: runes
หัวข้อที่มีชื่อว่า “แนวคิดหลัก: runes”Svelte 5 แนะนำ runes — primitives พิเศษที่ compiler เข้าใจ ซึ่งมาแทนที่ React hooks:
$stateแทนuseState— ประกาศตัวแปร reactive$derivedแทนuseMemo— คำนวณค่าที่อัปเดตเมื่อ dependencies เปลี่ยน$effectแทนuseEffect— รัน side effect ทุกครั้งที่ reactive values ที่อ่านอยู่มีการเปลี่ยนแปลง
ต่างจาก React hooks ตรงที่ runes ไม่ใช่ function calls ที่มีกฎมหัศจรรย์ — แต่เป็น compiler instructions ตัว Svelte compiler มองเห็น $state(0) แล้วสร้าง DOM update code แบบ fine-grained ไม่มีกฎของ hooks ไม่มี dependency arrays ไม่มีบั๊กจาก stale closures
Counter กับ derived state
หัวข้อที่มีชื่อว่า “Counter กับ derived state”function Counter() { const [count, setCount] = React.useState(0); const doubled = count * 2; return ( <div> <button onClick={() => setCount(c => c + 1)}>+</button> <p>Count: {count}</p> <p>Doubled: {doubled}</p> </div> );}<script> let count = $state(0); let doubled = $derived(count * 2);</script>
<button onclick={() => count++}>+</button><p>Count: {count}</p><p>Doubled: {doubled}</p>ความแตกต่างหลัก:
- React ต้องการ
setCount— คุณไม่สามารถเขียนcount++ได้เพราะcountเป็นconstธรรมดา Svelte ให้คุณกำหนดค่าตรงๆ ได้เลย doubledของ React จะถูกคำนวณใหม่ทุก render ส่วน$derivedของ Svelte ถูก track โดย compiler — จะคำนวณใหม่เฉพาะเมื่อcountเปลี่ยน- template ของ Svelte สั้นกว่าเพราะไม่มี wrapping function ไม่มี return และไม่มี JSX closing tags
Reactivity คือค่าเริ่มต้น
หัวข้อที่มีชื่อว่า “Reactivity คือค่าเริ่มต้น”ใน React คุณ เลือกเข้า สู่ reactivity: ทุกอย่างที่อยู่นอก useState หรือ useReducer จะไม่ reactive ใน Svelte คุณ เลือกออก: ตัวแปร $state ทุกตัว reactive ทุกที่ที่ถูกอ่าน ทั้งใน template ใน $derived expressions และใน $effect callbacks
ซึ่งหมายความว่าคุณสามารถ refactor ได้อย่างอิสระ แยก helper function ที่อ่าน $state ออกมา — ยังคง reactive ส่งค่า $state ไปยัง child component — ก็ยังคง reactive compiler track การ reads ไม่ใช่ call sites
$effect โดยไม่มี dependency arrays
หัวข้อที่มีชื่อว่า “$effect โดยไม่มี dependency arrays”useEffect ของ React ต้องการ dependency array ถ้าใส่ผิดก็จะเกิดทั้ง stale closure หรือ infinite loop $effect ของ Svelte auto-track ทุก $state และ $derived value ที่อ่านภายใน — ไม่ต้องมี array:
// React — คุณต้องระบุทุก dependencyuseEffect(() => { document.title = `Count: ${count}`;}, [count]);
// Svelte 5 — compiler track dependencies อัตโนมัติ$effect(() => { document.title = `Count: ${count}`;});ถ้า count เปลี่ยน effect จะรันใหม่ ถ้าคุณเพิ่มตัวแปร $state อื่นเข้าไปใน effect ทีหลัง จะถูก track อัตโนมัติ ไม่มี dependencies ที่พลาด ไม่มี lint warnings
ลองเลย: runes ในการใช้งานจริง
หัวข้อที่มีชื่อว่า “ลองเลย: runes ในการใช้งานจริง”Playground นี้แสดง runes ทั้งสามตัวในการทำงาน: $state สำหรับตัวแปร reactive, $derived สำหรับค่าที่คำนวณจาก count, และ $effect สำหรับอัปเดต message ตาม count — ทั้งหมดโดยไม่มี dependency arrays หรือ setters