Svelte Basics - Props and State - Part 2

Svelte Basics - Props and State - Part 2

Learn more about Svelte state and props in this post. You can understand how svelte is handling state updates and what are props in Svlete.

Svelte Basics - Props and State

This is part 2 of a course on Svelte. If you haven’t seen the previous part, it will be useful to know the basics discussed in the last part. Just have a quick glance at this link

https://www.eternaldev.com/blog/svelte-basics-introduction-to-svelte

What are props in Svelte?

Props in Svelte are used to pass data from one component to another.

We have already discussed passing inputs to components in the previous post. The inputs to the component are called props (short for properties). This is a term used in a lot of front-end frameworks which means you are passing some properties from the parent component to a child component. These properties are used by the component to determine its internal logic on how to display the component.

Parent Component → Passing props → Child component

<ChildComponent selectedProject={'Project1'} allProjects={["Project1", "Project2"]} />

selectedProject and allProjects are the props for the ChildComponent

Examples of using props in Svelte

Props are commonly used to pass data from the parent to the child. Let’s look at the example of rendering a list of projects and showing the selected project.

Example of props - Svelte REPL

<script>
	export let selectedProject;
	export let allProjects;
</script>

<h2>All Projects</h2>
<ul>
	{#each allProjects as project}
		<li>{project}</li>
	{/each}
</ul>

<h3>Selected Project: {selectedProject}</h3>

In this example, we are getting a couple of props from the parent component

  1. selectedProject props are just displayed on the component
  2. allProjects is an array prop that can be used to loop through and display all the items inside the array using the #each syntax. (We will cover this syntax in more depth in later lessons)

Default props in Svelte

You can have a default value for a prop if that is not passed from the parent. This can be useful if you don’t want the component to show undefined when the prop is not passed from the parent.

<script>
	export let selectedProject ='None';
	export let allProjects = [];
</script>

We are setting the default value of both the props in this example. selectedProject will show as “None” if it is not passed. allProjects will show as an empty array if that is not passed.

This can also be helpful if you are using Svelte without Typescript and you want to have some assumptions about the types of props.

What is a state in Svelte?

The state is an internal set of variables that define how the component should behave.

You can make the component update its display based on internal logic specific to the component. For example, you want to display a list of pokemon and you have a search box that will let the user filter the pokemon list. You might want to show “Pokemon not found” when the searched result is not present in the pokemon list. You can achieve this using the state of the component.

<script>
	let pokemonResultCount;
</script>

{#if pokemonResultCount == 0}
	<h3>Pokemon not found</h3>
{:else}
	<!-- List of pokemon -->
{/if}

All variables defined inside the script tag without the export keyword become part of the component internal state. In this example, you can see pokemonResultCount is a state variable, and based on its value, we are displaying a message using the #if syntax (More on this in the later posts)

Updating state in Svelte

Updating a state variable is very easy in Svelte. You can just assign a new value to the variable and the Svelte takes care of updating the display based on the change of the state. This forms the basis of reactivity in Svelte as updating the state of the variable, triggers the re-render of the component and the value is automatically updated in the HTML dom.

<script>
	let clicked = 0;

	const onClick = () => {
		clicked = clicked + 1;
	}
</script>

<h1>You have clicked {clicked} times</h1>
<button on:click={() =>onClick()}>Update Click</button>

We have a button called Update Click and on click of the button, we are calling the onClick method. (More on this in the later posts)

We are updating the clicked variable on the execution of the method. When onClick method is executed, the value of the clicked variable is updated and since the <h1> element is dependent on its value, it is also updated to show the latest value. Wow! so simple, this is something which impressed us as it is very simple to understand than other frameworks.

Updating array and objects state in Svelte

Array updates can be done using the in-build methods like push, pop, slice but when updating an array element using these methods, Svelte does not understand that the variables are updated since these are not assignment statements.

Pushing item into an array variable in Svelte

We can go around this issue by assigning the variable again after performing the array operation

Options 1: Workaround (Not recommended)

<script>
	const onUpdate = () => {
		numbers.push(10);
		numbers = numbers; //Extra assignment to update the state
	}
</script>

Options 2: Using the spread operator

You can make use of the spread operator to perform the task which you want

<script>
	const onUpdate = () => {
		numbers = [...numbers, 10]
	}
</script>

This operation is similar to a push operation. The spread operator is used here to add all the previous items in the array and then adding 10 as the last element

Updating object property in Svelte

When updating an object, you need to make sure that the object is present on the left-hand side of the assignment for the reactivity to trigger in Svelte.

let mainObj = {
	insideObj: {
		prop1: 'Abc',
		prop2: 123
	}
}

let copyOFInsideObj = mainObj.insideObj;
copyOFInsideObj.prop1 = 'XYZ'; // This statement won't update the mainObj state

Consider we have a deeply nested object like mainObj. You can assign this object’s property to another variable and update that variable. Since objects in javascript are reference by default, it will update the object but the state will be updated in Svelte.

You can avoid this scenario by making sure mainObj is on the left-hand side of the assignment.

Props vs State in Svelte

Props are variables that are passed to the component from the parent. State are variables that are internally initialized and updated by the component. Props values should not be updated within the child component.

State variables can be initialized based on the value of a prop. State variables are internal and so can only be modified inside the component.

<script>
	export let selectedProject;
	export let allProjects;
	
	// State varaible initialized based on prop
	let projectLeng = allProjects.length;
</script>

You can also have a component that doesn’t have any state variables. You can just use the props passed to the component to display the template. These components are usually referred to as “Stateless” components.

Example of stateless component

<script>
	export let taxValue;
</script>

<h4>Your tax value is : {taxValue}</h4>