Snippets & Children
React ส่งเนื้อหา UI ให้ component ผ่าน children (JSX ที่อยู่ระหว่าง tag) หรือ render props (function ที่ return JSX) ส่วน Svelte 5 แทนที่ระบบ <slot> แบบเก่าด้วย snippets — ชิ้นส่วน template ที่นำกลับมาใช้ซ้ำได้ มีชื่อ และรับ parameter ได้ นิยามด้วย {#snippet} และ render ด้วย {@render} snippet ตัว default ยังคงชื่อ children อยู่ ดังนั้นการใช้งานพื้นฐานจึงรู้สึกคุ้นเคยทันที
Default children
หัวข้อที่มีชื่อว่า “Default children”// Card.jsxfunction Card({ children }) { return <div className="card">{children}</div>;}
// Usage:<Card> <p>Hello from inside!</p></Card><!-- Card.svelte --><script> let { children } = $props();</script>
<div class="card"> {@render children()}</div>
<!-- Usage in parent: --><!-- <Card><p>Hello from inside!</p></Card> -->prop children คือ snippet function — คุณต้องเรียกด้วย {@render children()} ส่วน {children} ของ React เป็นค่า (value) แต่ children ของ Svelte เป็น snippet ที่เรียกได้ (callable)
Named snippets (เหมือน named slot / render props)
หัวข้อที่มีชื่อว่า “Named snippets (เหมือน named slot / render props)”// Dialog.jsxfunction Dialog({ header, body, footer }) { return ( <div className="dialog"> <div className="dialog-header">{header}</div> <div className="dialog-body">{body}</div> <div className="dialog-footer">{footer}</div> </div> );}
// Usage:<Dialog header={<h2>Confirm</h2>} body={<p>Are you sure?</p>} footer={<button>OK</button>}/><!-- Dialog.svelte --><script> let { header, body, footer } = $props();</script>
<div class="dialog"> <div class="dialog-header">{@render header()}</div> <div class="dialog-body">{@render body()}</div> <div class="dialog-footer">{@render footer()}</div></div>
<!-- Usage in parent: --><!--<Dialog> {#snippet header()}<h2>Confirm</h2>{/snippet} {#snippet body()}<p>Are you sure?</p>{/snippet} {#snippet footer()}<button>OK</button>{/snippet}</Dialog>-->Snippets ที่มี parameter (แพตเทิร์น render props)
หัวข้อที่มีชื่อว่า “Snippets ที่มี parameter (แพตเทิร์น render props)”snippet รับ argument ได้ — สิ่งนี้แทนที่แพตเทิร์น render-prop ของ React ได้อย่างสะอาดสะอ้าน:
// List.jsxfunction List({ items, renderItem }) { return ( <ul> {items.map((item, i) => ( <li key={i}>{renderItem(item)}</li> ))} </ul> );}
// Usage:<List items={fruits} renderItem={fruit => <strong>{fruit}</strong>}/><!-- List.svelte --><script> let { items, renderItem } = $props();</script>
<ul> {#each items as item} <li>{@render renderItem(item)}</li> {/each}</ul>
<!-- Usage in parent:<List {items}> {#snippet renderItem(fruit)} <strong>{fruit}</strong> {/snippet}</List>-->