@ -35,15 +35,17 @@ On the other side, inside `MyComponent.svelte`, we can receive props with the `$
<p>this component is {+++adjective+++}</p>
```
## Default values
## Fallback values
Destructuring allows us to declare default values, which are used if the parent component does not set a given prop:
Destructuring allows us to declare fallback values, which are used if the parent component does not set a given prop:
```js
/// file: MyComponent.svelte
let { adjective = 'happy' } = $props();
```
> [!NOTE] Fallback values are not turned into reactive state proxies.
## Renaming props
We can also use the destructuring assignment to rename props, which is necessary if they're invalid identifiers, or a JavaScript keyword like `super`:
@ -60,6 +62,38 @@ Finally, we can use a _rest property_ to get, well, the rest of the props:
let { a, b, c, ...others } = $props();
```
## Updating props
References to a prop inside a component update when the prop itself updates — when `count` changes in `App.svelte`, it will also change inside `Child.svelte`. But the child component is able to temporarily override the prop value, which can be useful for unsaved emphemeral state ([demo](/playground/untitled#H4sIAAAAAAAAE6WQ0WrDMAxFf0WIQR0Wmu3VTQJln7HsIfVcZubIxlbGRvC_DzuBraN92qPula50tODZWB1RPi_IX16jLALWSOOUq6P3-_ihLWftNEZ9TVeOWBNHlNhGFYznfqCBzeRdYHh6M_YVzsFNsNs3pdpGd4eBcqPVDMrNxNDBXeSRtXioDgO1zU8ataeZ2RE4Utao924RFXQ9iHXwvoPHKpW1xY4g_Bg0cSVhKS0p560Za95612ZC02ONrD8ZJYdZp_rGQ37ff_mSP86Np2TWZaNNmdcH56P4P67K66_SXoK9pG-5dF5Z9QEAAA==)):
<!-- prettier-ignore -->
```svelte
/// file: App.svelte
<script>
import Child from './Child.svelte';
let count = $state(0);
</script>
<buttononclick={()=> (count += 1)}>
clicks (parent): {count}
</button>
<Child{count}/>
```
<!-- prettier-ignore -->
```svelte
/// file: Child.svelte
<script>
let { count } = $props();
</script>
<buttononclick={()=> (count += 1)}>
clicks (child): {count}
</button>
```
## Type safety
You can add type safety to your components by annotating your props, as you would with any other variable declaration. In TypeScript that might look like this...
Ordinarily, props go one way, from parent to child. This makes it easy to understand how data flows around your app.
In Svelte, component props can be _bound_, which means that data can also flow _up_ from child to parent. This isn't something you should do often, but it can simplify your code if used sparingly and carefully.
It also means that a state proxy can be _mutated_ in the child.
> [!NOTE] Mutation is also possible with normal props, but is strongly discouraged — Svelte will warn you if it detects that a component is mutating state it does not 'own'.
To mark a prop as bindable, we use the `$bindable` rune:
<!-- prettier-ignore -->
```svelte
/// file: FancyInput.svelte
<script>
let { value = $bindable(), ...props } = $props();
</script>
<inputbind:value={value}{...props}/>
<style>
input {
font-family: 'Comic Sans MS';
color: deeppink;
}
</style>
```
Now, a component that uses `<FancyInput>` can add the [`bind:`](bind) directive ([demo](/playground/untitled#H4sIAAAAAAAAE3WQwWrDMBBEf2URBSfg2nfFMZRCoYeecqx6UJx1IyqvhLUONcb_XqSkTUOSk1az7DBvJtEai0HI90nw6FHIJIhckO7i78n7IhzQctS2OuAtvXHESByEFFVoeuO5VqTYdN71DC-amvGV_MDQ9q6DrCjP0skkWymKJxYZOgxBfyKs4SGwZlxke7TWZcuVoqo8-1P1z3lraCcP2g64nk4GM5S1osrXf0JV-lrkgvGbheR-wDm_g30V8JL-1vpOCZFogpQsEsWcemtxscyhKArfOx9gjps0Lq4hzRVfemaYfu-PoIqqwKPFY_XpaIqj4tYRP7a6M3aUkD27zjSw0RTgbZN6Z8WNs66XsEP03tBXUueUJFlelvYx_wCuI3leNwIAAA==)):
<!-- prettier-ignore -->
```svelte
/// App.svelte
<script>
import FancyInput from './FancyInput.svelte';
let message = $state('hello');
</script>
<FancyInputbind:value={message}/>
<p>{message}</p>
```
The parent component doesn't _have_ to use `bind:` — it can just pass a normal prop. Some parents don't want to listen to what their children have to say.
In this case, you can specify a fallback value for when no prop is passed at all:
```js
/// file: FancyInput.svelte
let { value = $bindable('fallback'), ...props } = $props();