Skip to main content

$props

Les données d’entrée d’un composant sont appelées des props, abbréviation de propriétés. Vous pouvez fournir des props aux composants de la même manière que vous passeriez des attributs aux éléments :

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

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

<MyComponent adjective="cool" />

De l’autre côté, dans MyComponent.svelte, les props sont accessibles grâce à la rune $props...

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

<p>ce composant est {props.adjective}</p>
<script lang="ts">
	let props = $props();
</script>

<p>ce composant est {props.adjective}</p>

... bien que plus souvent, il est plus pratique de déstructurer vos props :

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

<p>ce composant est {adjective}</p>
<script lang="ts">
	let { adjective } = $props();
</script>

<p>ce composant est {adjective}</p>

Valeurs par défaut

Déstructurer permet de déclarer des valeurs par défaut, qui sont utilisées si le composant parent ne définit pas une prop donnée :

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

Declares the props that a component accepts. Example:

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

https://svelte.dev/docs/svelte/$props

$props
();

Les valeurs par défaut ne sont pas transformées en proxys d’état réactifs (voir Mise à jour des props pour plus d’infos).

Renommer des props

Vous pouvez aussi utiliser la syntaxe d’assignation par déstructuration pour renommer des props, ce qui est nécessaire si leur identifiant est invalide ou si c’est un mot-clé réservé par JavaScript, comme super :

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

Declares the props that a component accepts. Example:

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

https://svelte.dev/docs/svelte/$props

$props
();

Props de reste

Enfin, nous pouvons utiliser une propriété de reste pour obtenir, eh bien, le reste des props :

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

Declares the props that a component accepts. Example:

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

https://svelte.dev/docs/svelte/$props

$props
();

Mise à jour des props

Les références à une prop à l’intérieur d’un composant se mettent à jour lorque la prop elle-même se met à jour — lorsque count change dans App.svelte, elle va également changer dans Child.svelte. Mais le composant enfant est capable d’écraser la valeur de la prop, ce qui peut être utile pour des états temporaires qui ne seront pas sauvegardés (démo).

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

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

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

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

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

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

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

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

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

Bien que vous puissiez temporairement réassigner des props, vous ne devriez pas muter de props, à moins qu’elles soient définies comme bindable.

Si une props est un objet classique, la mutation n’aura aucun effet (démo :

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

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

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

<button onclick={() => {
	// n'a aucun effet
	object.count += 1
}}>
	clicks: {object.count}
</button>
<script lang="ts">
	let { object } = $props();
</script>

<button onclick={() => {
	// n'a aucun effet
	object.count += 1
}}>
	clicks: {object.count}
</button>

Toutefois, si la props est un proxy réactif, les mutations auront un effet, mais vous aurez un warning _ownership_invalid_mutation, car le composant mute un état qui ne lui “appartient” pas (démo) :

App
<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} />
Child
<script>
	let { object } = $props();
</script>

<button onclick={() => {
	// va mettre à jour le count ci-dessous,
	// mais avec un warning. Ne mutez pas
	// des objets que vous ne possédez pas !
	object.count += 1
}}>
	clics: {object.count}
</button>
<script lang="ts">
	let { object } = $props();
</script>

<button onclick={() => {
	// va mettre à jour le count ci-dessous,
	// mais avec un warning. Ne mutez pas
	// des objets que vous ne possédez pas !
	object.count += 1
}}>
	clics: {object.count}
</button>

La valeur par défaut d’une prop non déclarée avec $bindable n’est pas affectée — elle n’est pas tranformée en proxy réactif d’état — ce qui implique que les mutations ne provoqueront pas de mise à jour (démo) :

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

<button onclick={() => {
	// n'a pas d'éffet si la valeur par défaut est utilisée
	object.count += 1
}}>
	clics: {object.count}
</button>
<script lang="ts">
	let { object = { count: 0 } } = $props();
</script>

<button onclick={() => {
	// n'a pas d'éffet si la valeur par défaut est utilisée
	object.count += 1
}}>
	clics: {object.count}
</button>

En résumé : ne mutez pas les props. Vous pouvez soit utiliser des props de callback pour communiquer des changements, ou — si le parent et l’enfant partagent le même objet — utiliser la rune $bindable.

Typage

Vous pouvez ajouter du typage à vos composants en annotant vos props, comme vous le feriez avec toute autre déclaration de variable. En TypeScript, cela peut ressembler à ça...

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

... tandis qu’en JSDoc vous pouvez écrire ceci :

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

Vous pouvez, bien sûr, séparer la déclaration de type de l’annotation :

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

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

Les interfaces des éléments natifs du DOM sont fournies par le module svelte/elements (voir Typer des composants haut-niveau).

L’ajout de types est recommandé, car il permet aux personnes utilisant votre composant de découvrir facilement les props à fournir.

Modifier cette page sur Github

précédent suivant