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

Mental Shift จาก React สู่ Svelte

โมเดลความคิดของ React ถูกสร้างขึ้นบน immutability และ explicit setters คุณเรียก useState เพื่อรับ value และ setter แล้วต้องเรียก setter ทุกครั้งที่ต้องการอัปเดต Svelte 5 พลิกแนวคิดนี้ทั้งหมด — การกำหนดค่าคือ reactivity เขียน count++ แล้ว DOM จะอัปเดตเอง ไม่ต้องมี setter ไม่ต้องมี dispatch ไม่ต้องมีพิธีกรรมใดๆ

นี่คือการเปลี่ยนแปลงที่ใหญ่ที่สุดเพียงหนึ่งเดียวเมื่อย้ายจาก React ไปสู่ Svelte

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

React
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>
);
}
Svelte
<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

ใน 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

useEffect ของ React ต้องการ dependency array ถ้าใส่ผิดก็จะเกิดทั้ง stale closure หรือ infinite loop $effect ของ Svelte auto-track ทุก $state และ $derived value ที่อ่านภายใน — ไม่ต้องมี array:

// React — คุณต้องระบุทุก dependency
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]);
// Svelte 5 — compiler track dependencies อัตโนมัติ
$effect(() => {
document.title = `Count: ${count}`;
});

ถ้า count เปลี่ยน effect จะรันใหม่ ถ้าคุณเพิ่มตัวแปร $state อื่นเข้าไปใน effect ทีหลัง จะถูก track อัตโนมัติ ไม่มี dependencies ที่พลาด ไม่มี lint warnings

Playground นี้แสดง runes ทั้งสามตัวในการทำงาน: $state สำหรับตัวแปร reactive, $derived สำหรับค่าที่คำนวณจาก count, และ $effect สำหรับอัปเดต message ตาม count — ทั้งหมดโดยไม่มี dependency arrays หรือ setters

คุณ update reactive state ใน Svelte 5 อย่างไร?
อะไรคือ Svelte 5 เทียบเท่ากับ useMemo ของ React?
อะไรคือ Svelte 5 เทียบเท่ากับ useEffect ของ React?
ใน Svelte 5 เมื่อคุณเขียน `count++` จะเกิดอะไรขึ้น?