Svelte – Learn props, set default value & pass as object in component

Total
0
Shares

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.

    Tweet this to help others

Live Demo

Open Live Demo