Two-Way Binding with `bind:` and `$bindable` in Svelte

Introduction to Two-Way Data Binding

In the previous lesson, you learned how to use callback functions as props to enable communication between parent and child components. This allowed the child to notify the parent when an event occurred, such as a button click. Now, we’ll take this concept further by introducing two-way data binding, a powerful feature in Svelte that simplifies synchronizing data between components.

Two-way data binding ensures that changes in one component are automatically reflected in another. For example, if a parent component passes a value to a child component, and the child updates that value, the parent’s state will also update automatically. This eliminates the need for manual callbacks in many cases, making your code cleaner and more intuitive.

In this lesson, you’ll learn how to implement two-way binding using bind: in parent components and $bindable in child components. By the end, you’ll be able to create seamless data synchronization between components, enhancing the interactivity of your Svelte applications.

One-Way vs. Two-Way Data Binding

Before diving into two-way binding, let's briefly discuss one-way data binding and how it differs from two-way binding.

Imagine water flowing down a river. It moves in only one direction, from the source to the ocean, and any changes at the source affect everything downstream. This is similar to one-way data binding, where data flows in a single direction—either from a component’s state to the UI or from a parent component to a child component. Changes in the state update the UI, but user interactions with the UI do not modify the state directly.

Svelte
<!-- App.svelte -->
<script lang="ts">
  let message: string = $state("Hello, Svelte!");
</script>

<p>{message}</p>

Here, message is displayed in the <p> tag, but modifying the displayed text in the UI won't change message in the script.

Now, think of a conversation between two people. Each person speaks and listens, responding to changes in real time. This is like two-way data binding, where data flows in both directions—updates to the UI affect the state, and updates to the state affect the UI.

<!-- App.svelte -->
<script lang="ts">
  let name: string = $state("Alice");
</script>

<input type="text" bind:value={name} />
<p>Hello, {name}!</p>

Typing in the input field updates name, and any changes in name also reflect in the UI.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal