Skip to main content

$props

コンポーネントへの入力は props (プロパティの省略形) と呼ばれます。属性を要素に渡すのと同じように、props をコンポーネントに渡します:

App
<script>
	import MyComponent from './MyComponent.svelte';
</script>

<MyComponent adjective="cool" />
<script lang="ts">
	import MyComponent from './MyComponent.svelte';
</script>

<MyComponent adjective="cool" />

それに対し、MyComponent.svelte の内部では、$props rune を使用して props を受け取ることができます...

MyComponent
<script>
	let props = $props();
</script>

<p>this component is {props.adjective}</p>
<script lang="ts">
	let props = $props();
</script>

<p>this component is {props.adjective}</p>

...ただし、一般的には props を 分割代入 することが多いです:

MyComponent
<script>
	let { adjective } = $props();
</script>

<p>this component is {adjective}</p>
<script lang="ts">
	let { adjective } = $props();
</script>

<p>this component is {adjective}</p>

Fallback values

分割代入を使用するとフォールバック値を宣言できます。これは親コンポーネントが特定の props を設定しない場合に使用されます (フォールバック値がなく、親コンポーネントから設定されない場合、その値は undefined になります):

let { let adjective: anyadjective = 'happy' } = 
function $props(): any
namespace $props

Declares the props that a component accepts. Example:

let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
@see
$props
();

フォールバック値はリアクティブな state proxy には変換されません (Updating props を参照してください)

Renaming props

分割代入を使用して props をリネームすることもできます。これは元の props の名前が無効な識別子や super のような JavaScript キーワードである場合に必要となります:

let { super: let trouper: anytrouper = 'lights are gonna find me' } = 
function $props(): any
namespace $props

Declares the props that a component accepts. Example:

let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
@see
$props
();

Rest props

最後に、rest property を使用して、他のすべての props を取得できます:

let { let a: anya, let b: anyb, let c: anyc, ...let others: anyothers } = 
function $props(): any
namespace $props

Declares the props that a component accepts. Example:

let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
@see
$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 ephemeral state:

<script>
	import Child from './Child.svelte';

	let count = $state(0);
</script>

<button onclick={() => (count += 1)}>
	clicks (parent): {count}
</button>

<Child {count} />
<script lang="ts">
	import Child from './Child.svelte';

	let count = $state(0);
</script>

<button onclick={() => (count += 1)}>
	clicks (parent): {count}
</button>

<Child {count} />
<script>
	let { count } = $props();
</script>

<button onclick={() => (count += 1)}>
	clicks (child): {count}
</button>
<script lang="ts">
	let { count } = $props();
</script>

<button onclick={() => (count += 1)}>
	clicks (child): {count}
</button>

props は一時的に再代入(reassign)することができます。一方で、bindable でない限り変異(mutate)すべきではありません。

If the prop is a regular object, the mutation will have no effect:

<script>
	import Child from './Child.svelte';
</script>

<Child object={{ count: 0 }} />
<script lang="ts">
	import Child from './Child.svelte';
</script>

<Child object={{ count: 0 }} />
<script>
	let { object } = $props();
</script>

<button onclick={() => {
	// has no effect
	object.count += 1
}}>
	clicks: {object.count}
</button>
<script lang="ts">
	let { object } = $props();
</script>

<button onclick={() => {
	// has no effect
	object.count += 1
}}>
	clicks: {object.count}
</button>

If the prop is a reactive state proxy, however, then mutations will have an effect but you will see an ownership_invalid_mutation warning, because the component is mutating state that does not 'belong' to it:

<script>
	import Child from './Child.svelte';

	let object = $state({count: 0});
</script>

<Child {object} />
<script lang="ts">
	import Child from './Child.svelte';

	let object = $state({count: 0});
</script>

<Child {object} />
<script>
	let { object } = $props();
</script>

<button onclick={() => {
	// will cause the count below to update,
	// but with a warning. Don't mutate
	// objects you don't own!
	object.count += 1
}}>
	clicks: {object.count}
</button>
<script lang="ts">
	let { object } = $props();
</script>

<button onclick={() => {
	// will cause the count below to update,
	// but with a warning. Don't mutate
	// objects you don't own!
	object.count += 1
}}>
	clicks: {object.count}
</button>

The fallback value of a prop not declared with $bindable is left untouched — it is not turned into a reactive state proxy — meaning mutations will not cause updates:

<script>
	import Child from './Child.svelte';
</script>

<Child />
<script lang="ts">
	import Child from './Child.svelte';
</script>

<Child />
<script>
	let { object = { count: 0 } } = $props();
</script>

<button onclick={() => {
	// has no effect if the fallback value is used
	object.count += 1
}}>
	clicks: {object.count}
</button>
<script lang="ts">
	let { object = { count: 0 } } = $props();
</script>

<button onclick={() => {
	// has no effect if the fallback value is used
	object.count += 1
}}>
	clicks: {object.count}
</button>

要約: props を変異(mutate)しないでください。変更を伝えるためにコールバック props を使用するか、親と子が同じオブジェクトを共有する必要がある場合は $bindable rune を使用してください。

Type safety

他の変数宣言と同様に、props にアノテーションを付けることでコンポーネントに型安全性を追加できます。TypeScript では次のようになります...

<script lang="ts">
	let { adjective }: { adjective: string } = $props();
</script>

...一方、JSDoc では次のようにできます:

<script>
	/** @type {{ adjective: string }} */
	let { adjective } = $props();
</script>

もちろん、型宣言をアノテーションから分離することもできます:

<script lang="ts">
	interface Props {
		adjective: string;
	}

	let { adjective }: Props = $props();
</script>

ネイティブ DOM 要素用のインターフェースは svelte/elements モジュールで提供されています (Typing wrapper components を参照してください)

If your component exposes snippet props like children, these should be typed using the Snippet interface imported from 'svelte' — see Typing snippets for examples.

Adding types is recommended, as it ensures that people using your component can easily discover which props they should provide.

$props.id()

This rune, added in version 5.20.0, generates an ID that is unique to the current component instance. When hydrating a server-rendered component, the value will be consistent between server and client.

This is useful for linking elements via attributes like for and aria-labelledby.

<script>
	const uid = $props.id();
</script>

<form>
	<label for="{uid}-firstname">First Name: </label>
	<input id="{uid}-firstname" type="text" />

	<label for="{uid}-lastname">Last Name: </label>
	<input id="{uid}-lastname" type="text" />
</form>

Edit this page on GitHub llms.txt

previous next