In javascript frameworks, props is an important concept. Without them it’s not easy to pass data from one component to another. So, the primary use of props is to pass messages. In React, this works in parent to children hierarchy but in Svelte this could be both ways. In this article we will learn about declaring props, setting a default value to them and passing them as object to the component.
Declaring a prop
To declare a prop, we need to prefix the statement with export
keyword. Any variable declared with export
will automatically become prop. For example, let’s define a component, Child.svelte
–
<script> export let thisVariableIsProp </script> <p> This value will be passed by parent component - {thisVariableIsProp} </p>
Now you can use this in a parent component, suppose App.svelte
–
<script> import Child from './Child' </script> <Child thisVariableIsProp={'Passed from App.svelte'} />
Check the rendered output in the demo below.
Setting default props value
It’s easy to set a default value to a prop. Simply pass a value while declaring it –
<script> export let thisVariableIsProp = 'I am default value' </script> <p> This value will be passed by parent component or will show default value - {thisVariableIsProp} </p>
Check the rendered output in live demo.
Passing props as object in component
When there are many props then it’s a good practice to create an object with keys as their names and pass that object as props. This is done by spread operator (...
). For example, let’s create a new svelte file, ManyProps.svelte
–
<script> export let name export let screenName export let franchise export let weapon </script> <p>I am a superhero -</p> <pre> Name - {name} Screen Name - {screenName} Franchise - {franchise} Weapon - {weapon} </pre>
This file has many props like name
, screenName
, franchise
and weapon
. Now to pass the values in these props, we can simply call this component like this –
<ManyProps name={'Tony Stark'} screenName={'Ironman'} franchise={'Marvel'} weapon={'Suit'} />
Or, we can define an object of props and pass it to component with the help of spread operator like this –
<script> var propsObject = { name : 'Kal El', screenName: 'Superman', franchise: 'DC', weapon: 'Everything' } </script> <ManyProps {...propsObject} />
Creating 2-way binding
Generally the parent component passes the props values to child components. But in Svelte, there could be a 2-way binding which means a variable defined in both components could be synchronized and its value can be changed by any component. The change will be reflected in both places.
This can be done by using bind
attribute. The syntax is this –
<Child bind:thisVariableIsProp={variableInParent} />
So now the thisVariableIsProp
and variableInParent
are synchronized with values. variableInParent
is available to parent component while thisVariableIsProp
is in Child component. Check this code –
PropsBinding.svelte
<script> export var someProp = 0; </script> <p>Value of prop in child - {someProp}</p> <p> Change value of prop from child <input type="text" value={someProp} on:keyup={e => someProp = e.target.value} /> </p>
This is a normal child component where we are declaring a prop variable someProp
. It’s value can be updated from the input field. Remeber, this is a prop. So, its value is provided from parent component. But we can still update the value from here.
Now, let’s use this in parent component –
<script> import PropsBinding from "./PropsBinding"; var forPropsBindingExample; </script> <p> Value of variable in Parent - {forPropsBindingExample} </p> <p> Change value from Parent - <input type="text" value={forPropsBindingExample} on:keyup={e => forPropsBindingExample = e.target.value} /> </p> <PropsBinding bind:someProp={forPropsBindingExample} />
In this parent component we declared another variable forPropsBindingExample
. This is passed as props value for PropsBinding
component using bind:someProp
. Since we used bind:
syntax, both someProp
and forPropsBindingExample
now holds same value always.
You can check this example in live demo below.
Props as function
You may also define function as props values. It means you can pass a function from parent to get executed by child component. For example, create a component FunctionProps.svelte
–
<script> export var functionProp = num => { return num * num; }; </script> <p> This is function prop. Default function does square of number. Number used is 5 - <strong>{functionProp(5)}</strong> </p>
Here we declared a prop, functionProp
whose default value is a function which returns the square of provided number. Since we provided 5 so the return value will be 25.
Now let’s use it in parent –
<script> import FunctionProps from "./FunctionProps"; </script> <p> 1. Using default function defined in child </p> <FunctionProps /> <p> 2. Passing custom function as prop. It will do cube </p> <FunctionProps functionProp={num => num * num * num} />
From parent we are passing a new function as the value of functionProp
. This function will do the cube of provided number. Since we called the prop with number 5 so the answer will be 125 now.
You may check this example in live demo below.
Readonly props
We can define readonly props too. It means their values can be read by parent component using child component reference variable but they can’t change their values by passing as props. In one sense, these variables are not props, else they are exported constants. We can define a reference variable using bind:this
.
To make a prop read only, we have to make sure that it’s value could not change. This is done by const
. So, instead of using let
or var
while declaring a prop, if you use const
then that will become read only. Use export const someProp
. A function defined in export is also read only – export function someFunc(){}
For example, consider a component, ReadonlyProps.svelte
–
<script> export const readOnlyProp = "Its value cannot change"; export function readOnlyFunction(num) { return num * num; } </script> <p> Readonly Prop - <strong>{readOnlyProp}</strong> </p> <p> Readonly function (used value 5) - <strong>{readOnlyFunction(5)}</strong> </p>
Use this in parent component and access the props using binding –
<script> import ReadonlyProps from "./ReadonlyProps"; // Binding variable needs to be var or let var bindingVariable; </script> <ReadonlyProps bind:this={bindingVariable} /> <p>Using readonly props in parent component</p> <p> Variable - {bindingVariable && bindingVariable.readOnlyProp} </p> <p> Function (using value 10) - {bindingVariable && bindingVariable.readOnlyFunction(10)} </p>
Make sure that binding variable is let or var. It won’t work with const because it’s value changes are declaration. Also pay attention to bindingVariable && bindingVariable.readOnlyProp
. This is used to ensure that bindingVariable
is not undefined while reading readOnlyProp
.
Find this example in live demo.