Svelte from a React developer's perspective part 2: Reactivity & Props
Tags: svelte, react
Published: 2020-02-17 21:46:53

---
title: Svelte from a React developer's perspective part 2: Reactivity & Props
published: true
date: 2020-02-17 00:00:00 UTC
tags: svelte, react
canonical_url: https://www.delvalle.dev/posts/svelte-from-react-perspective-part-2/svelte-from-react-perspective-part-2/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/v7297vgbted7msd59be1.jpg
---

In the [previous article](https://delvalle.dev/posts/svelte-from-react-perspective-basics/svelte-from-react-perspective-part-1/) I introduced myself into Svelte and explained some of the basics from a React developer's perspective. Today, I'm getting into it more in-depth and will explore how to derive values from state and how to pass props to child components while comparing Svelte's approach with React's.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#computed-values)Computed Values

Svelte calls these _Reactive Declarations_. With some special syntax, you can declare variables whose values will be derived from other variables. Let's say you have variable **b** whose value is derived from what variable **a** contains. Each time the value of **a** changes, the value of **b** will be recomputed.

The way of writing _Reactive Declarations_ is by using a **$:** before the variable's declaration.In the following example, we compute or derive the variable **age** from the variable **birthyear** and each time we change the value of **birthyear** via the input element, the value of **age** will also be updated.

```html
<script>
    let birthyear = 1993;
    let currentYear = new Date().getFullYear();
    $: age = currentYear - birthyear;

    function handleChange(e) {
        birthyear = e.target.value;
    }
</script>

<input 
    type="number" 
    id="birthyear" 
    name="birthyear" 
    min="1960" max="2020" 
    value={birthyear} 
    on:change={handleChange}
>

<p>Your age is {age}</p>
```

_Reactive Declarations_ are useful when you want to reuse them in several places, so you don't have to do the computations over and over again.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#reactive-statements)Reactive Statements

Following the previous approach, you can also use _Reactive Statements_ and put the **$:** before things like **if** or **console.log** statements. This can be useful if you only want to execute stuff if your variable in the state meets certain criteria.

Anywhere inside your **script** block you can do things like:

```html
<script>
// Single statment
$: console.log(`Logging the value of ${age}`);

// Grouped statements
$: {
    alert(`Your year of birth is: ${birthyear}`);
    console.log(`Your age is: ${age}`);
}

// Conditional
$: if (age <= 20) {
    console.log('Hey you are still young!')
}

// Conditional Re-Setting Value
$: if (age < 18) {
    alert(`People less than 18 y/o are not allowed`);
    age = 18;
} 
</script>
```

Coming from **React** you may think all this may be unnecessary, given the fact that when working with React, if you want to have computed or derived values you just assign a computation to a variable. Depending on where you declare this computation it will run each time the state or the props change, or you can have it in a function that you can call whenever you want. All this without additional syntax.

Still, Svelte keeps this pretty simple and easy to remember so this shouldn't be a big obstacle.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#updating-arrays-and-objects)Updating Arrays and Objects

React's rule of thumb is that you do not mutate the state directly. You have to make use of React's **setState** or **hooks**. By using them you make sure your state updates accordingly and your components _react_ and re-render.

Svelte works the same way behind the scenes, although you don't have any setState or hooks.If you have an array and you push a value to it, there won't be any state update, unless you make a reassignment of that array with the updated value.

I see this re-assignment as our **setState** from React because it is this re-assignment that triggers the _reactivity_ in Svelte.

As mentioned in the Svelte tutorial:

> Svelte's reactivity is triggered by assignments.

I took the example from the tutorial and commented it to make this easier to understand:

```html
<script>
    let numbers = [1, 2, 3, 4];

    function addNumber() {
        // We push a new value to the array
        // this won't trigger any state update
        numbers.push(numbers.length + 1);
        // We re-assign the updated array to the same variable
        // I see this as our setState or hook setter from React
        // Without this, there're no state updates
        numbers = numbers;

        // Instead of all this you can also do just
        // numbers = [...numbers, numbers.length + 1];
    }
</script>

<p>{numbers.join(' + ')}</p>

<button on:click={addNumber}>
    Add a number
</button>
```

When working with **objects** it gets kind of tricky because you have to understand how references work in Javascript. When assigning an object to a variable, this variable doesn't get a new copy of that object, instead, it gets a **reference** to the original object. This means that if you mutate a property on the newly declared one, it will also mutate the property from the original object.

Having said that, still after the mutation Svelte won't know that the state has to be updated, **unless you make an assignment**.

Again, a commented example would make this easier to understand:

```html
<script>
    let obj = {
        foo: {
            bar: 'bar'
        }
    }

    function updateProperty() {
        // foo has a reference to obj.foo
        const foo = obj.foo;
        // Mutating foo.bar also mutates obj.foo.bar
        foo.bar = 'baz';
        // But you need a re-assignment of 'obj'
        // So Svelte updates the state accordingly
        obj = obj;
    }
    </script>

<p>
    {obj.foo.bar}
</p>

<button on:click={updateProperty}>
    Update Property
</button>
```

Now, the following also worked for me, by directly assigning the new value to **obj.foo.bar**.

```javascript
function updateProperty() {
    obj.foo.bar = 'baz';
}
```

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#props)Props

We're finally talking about properties or just _props_. Just like React, we can pass properties down to our child components and the concept is the same. Svelte does it in a slightly different way tho.

In the next example, we are going to import a **Child** component and we're gonna pass a property called **age** to it. So far this is very similar to React.

```html
<script>
    import Child from './Child.svelte';
</script>

<Child age={10}/>
```

Now, there's a difference in how this looks on the **Child** component. In React, you receive the props via the parameters in a functional component or via **this.props** in a class component and that's pretty much it.

In Svelte tho, this is how it would look on the **Child** component:

```html
<script>
    export let age;
</script>

<p>My age is {age}</p>
```

At first glance, this doesn't make sense. Why would we want to use **export** when we want to use a property we are receiving from our parent component? Well, although it doesn't make sense from a semantical standpoint my interpretation is that we are _exposing_ the property to the rest of our component so we can use it in our elements below.

#### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#default-props)Default Props

We can specify default values for the props in the Child component just like this:

```html
<script>
    export let age = 0;
</script>
```

This way, if the component doesn't receive the property we can show a value instead of _undefined_. This is the same as React's **defaultProps** but with a little bit of less code.

#### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#spread-props)Spread Props

And last but not least, we can use our friend the **spread** operator when we want to pass several properties to our children.

So instead of doing this:

```html
<User name={userInfo.name} age={userInfo.age} email={userInfo.email}/>
```

We can do the following:

```html
<script>
    import User from './User.svelte';

    const userInfo = {
        name: 'José',
        age: 27
        email: 'jose@email.com'
    };
</script>

<User {...userInfo}/>
```

* * *

This is all for the second part, there's still a lot of topics to cover but I'll work on those during the following weeks. Thanks for reading and stay tuned!

*Follow me on twitter: [@jdelvx](https://twitter.com/jdelvx)*