The $effect Rune
effect sync กับโลกภายนอก
หัวข้อที่มีชื่อว่า “effect sync กับโลกภายนอก”$effect รัน function หลัง DOM update แล้ว และรันซ้ำทุกครั้งที่ค่า reactive ที่อ่านเปลี่ยน มีไว้สำหรับ side effect — sync state ของ Svelte กับสิ่งที่อยู่นอก Svelte: DOM ตรง ๆ, library ภายนอก, subscription, timer, logging, localStorage
<script> let count = $state(0);
$effect(() => { // Runs after render, and again whenever count changes. document.title = `Count: ${count}`; });</script>dependency ถูก track อัตโนมัติ เหมือน $derived เป๊ะ — effect อ่าน count จึงรันซ้ำเมื่อ count เปลี่ยน ไม่ต้องมี dependency array
Cleanup
หัวข้อที่มีชื่อว่า “Cleanup”ถ้า effect ตั้งอะไรบางอย่างที่ต้อง tear down — interval, event listener, subscription — ให้ return cleanup function Svelte จะรัน cleanup ก่อน effect รันซ้ำ และตอน component ถูก destroy
<script> let seconds = $state(0);
$effect(() => { const id = setInterval(() => seconds++, 1000); return () => clearInterval(id); // cleanup: runs before re-run and on destroy });</script>$effect.pre
หัวข้อที่มีชื่อว่า “$effect.pre”$effect รัน หลัง DOM update บางครั้งคุณต้องอ่าน DOM ก่อน DOM update — เช่น จับ scroll position ก่อน content ใหม่จะดันตำแหน่งไป $effect.pre รันก่อน DOM update แทน โดยมีกฎ track และ cleanup เหมือนกัน
<script> let messages = $state([]);
$effect.pre(() => { messages.length; // track the dependency // read scroll position BEFORE the DOM updates with new messages });</script>ส่วนใหญ่คุณไม่ต้องใช้ effect
หัวข้อที่มีชื่อว่า “ส่วนใหญ่คุณไม่ต้องใช้ effect”นี่คือแนวทางที่สำคัญที่สุดในโมดูล effect คือ escape hatch และการหยิบมาจัดการ state ภายใน คือความผิดพลาดที่พบบ่อยที่สุดใน Svelte 5 ก่อนเขียน effect ให้ถามว่า:
- คำนวณค่าจาก state? ใช้
$derivedไม่ใช่ effect ที่ assign state - ตอบสนอง user action? ทำงานใน event handler (
onclick) ไม่ใช่ effect ที่คอยดูตัวแปร - mirror prop ลง state? มักเป็น design smell — derive จาก prop แทน
flowchart TB q["ต้อง react ต่อ state?"] --> derive["คำนวณค่า? ใช้ $derived"] q --> handler["จาก user action? ใช้ event handler"] q --> effect["sync กับสิ่งนอก Svelte? ใช้ $effect"]
effect เป็นเครื่องมือที่ถูกก็ต่อเมื่อคุณเชื่อมไปยังสิ่งที่ Svelte ไม่ได้ควบคุม — document title, canvas, websocket, localStorage, analytics call ถ้างานยังอยู่ในโลก reactive ของ Svelte rune อย่าง $derived มักเหมาะกว่าเสมอ