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.- Sriram Thiagarajan
- March 21, 2022
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
selectedProject
props are just displayed on the componentallProjects
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>