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

Passing UI & Children

เมื่อคุณวาง markup ไว้ ระหว่าง tag ของ component, Svelte จะส่ง markup นั้นให้ component เป็น snippet prop ชื่อ children แล้ว component render ด้วย {@render children()}

Card.svelte
<script>
let { children } = $props();
</script>
<div class="card">
{@render children()} <!-- อะไรก็ตามที่ parent ใส่ nested เข้ามาอยู่ตรงนี้ -->
</div>
<!-- Parent -->
<Card>
<h2>Title</h2>
<p>markup ตรงนี้กลายเป็น children ของ card</p>
</Card>

นี่คือตัวเทียบเท่าของ React children (หรือ default <slot> ของ Svelte 4) ใน Svelte 5: component ห่อที่ reuse ได้โดยไม่ต้องรู้ว่าห่ออะไร

flowchart LR
  parent["Card ...markup... Card"] --> prop["child รับ children snippet"]
  prop --> render["render children()"]
  render --> out["markup render ในการ์ด"]
markup ที่ nested มาถึงเป็น children snippet

สำหรับ component ที่มีหลายจุดใส่ content (header, body, footer) ให้ส่ง named snippets เป็น props นิยามใน parent ด้วย {#snippet name()} ภายใน tag ของ component แล้ว child จะรับแต่ละอันเป็น prop

Modal.svelte
<script>
let { header, children, footer } = $props();
</script>
<div class="modal">
<div class="modal-header">{@render header()}</div>
<div class="modal-body">{@render children()}</div>
<div class="modal-footer">{@render footer()}</div>
</div>
<Modal>
{#snippet header()}<h2>Confirm</h2>{/snippet}
<p>Are you sure?</p> <!-- default children -->
{#snippet footer()}<button>OK</button>{/snippet}
</Modal>

เพราะ snippet รับพารามิเตอร์ได้ component จึงส่งข้อมูล ออก ไปให้ markup ที่ parent ให้มาได้ — pattern ที่ React เรียกว่า render props child เรียก snippet พร้อมค่า และ snippet ของ parent รับค่านั้นไปใช้:

List.svelte
<script>
let { items, row } = $props();
</script>
{#each items as item (item.id)}
{@render row(item)} <!-- ส่ง item แต่ละตัวกลับไปให้ snippet ของ parent -->
{/each}
<List items={products}>
{#snippet row(product)}
<li>{product.name} — ${product.price}</li> <!-- parent ตัดสินใจ markup -->
{/snippet}
</List>

child เป็นเจ้าของการวน iteration; parent เป็นเจ้าของ markup ต่อ item การกลับด้านนี้ — child ให้ข้อมูล, parent ให้การแสดงผล — คือ render-prop pattern ที่แสดงออกมาสวยงามด้วย snippet

component รับ markup ที่ nested ระหว่าง tag ของตัวเองยังไง?
ให้หลายจุดใส่ content แบบมีชื่อกับ component ยังไง?
component ส่งข้อมูลออกไปให้ markup ที่ parent ให้มา (render props) ยังไง?