Component Communication
Passing data down through props and sending updates back up through callback props.
2 phút đọc
Data flows into a component through props, as you've already seen. But components also need to talk upward — telling a parent "the user clicked delete" or "this value changed." In Svelte 5, the answer is the same tool in reverse: pass a function down as a prop, and call it from the child.
<!-- TodoItem.svelte -->
<script>
let { text, onRemove } = $props();
</script>
<li>
{text}
<button onclick={onRemove}>Remove</button>
</li><!-- App.svelte -->
<script>
import TodoItem from './TodoItem.svelte';
let todos = $state(['Buy milk', 'Walk the dog']);
function removeTodo(index) {
todos = todos.filter((_, i) => i !== index);
}
</script>
{#each todos as todo, i}
<TodoItem text={todo} onRemove={() => removeTodo(i)} />
{/each}The child never touches todos directly — it doesn't even know a list is involved. It just calls the function it was given. The parent decides what "remove" actually means, which keeps TodoItem reusable in contexts where removal might work completely differently.
Passing data along with the callback
A callback prop can take arguments, just like any function:
<!-- RatingStars.svelte -->
<script>
let { value, onChange } = $props();
</script>
{#each [1, 2, 3, 4, 5] as star}
<button onclick={() => onChange(star)}>
{star <= value ? '★' : '☆'}
</button>
{/each}<script>
let rating = $state(0);
</script>
<RatingStars value={rating} onChange={(star) => (rating = star)} />This is the same shape as a native DOM event handler receiving an event object — the child reports what happened, and the parent decides what to do about it.
Why this replaced createEventDispatcher
Older Svelte code often used createEventDispatcher() and dispatch('remove'), paired with on:remove on the parent's side. Svelte 5 favors plain callback props instead, for a simple reason: they're just JavaScript functions. There's no separate event system to learn, no string event names to keep in sync between dispatch and listener, and your editor can jump straight from the callback prop to its definition the same way it can for any other function reference.
The pattern, generalized
Props down, callbacks up — this one rule covers the overwhelming majority of parent-child communication in Svelte. Reach for shared state (covered in a later lesson) only when two components that aren't in a direct parent-child relationship need to affect each other.