Storing Shared State in a Svelte App
Tags: svelte, webdev, programming, javascript
Published: 2021-01-28 21:41:25

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


Svelte is an up and coming front end framework for developing front end web apps.

It’s simple to use and lets us create results fast.

In this article, we’ll look at how to store shared states in a Svelte store.

### Writable Stores

We can add a writable store to store data that are shared by multiple components.

For instance, we can write the following to create a store and use it in a component:

`App.svelte` :

```
<script>
  import { count } from "./stores.js";

  let countValue;

  const unsubscribe = count.subscribe(value => {
    countValue = value;
  });

  const increment = () => {
    count.update(n => n + 1);
  };
</script>

<button on:click={increment}>Increment</button>
<p>{countValue}</p>
```

`stores.js` :

```
import { writable } from "svelte/store";

export const count = writable(0);
```

In the code above, we created a shared writable state in `stores.js` called `count` .

Then we subscribed to it to get the latest value and set it to `count_value` .

We can also call the `set` method on `count` to reset the value as follows:

`App.svelte` :

```
<script>
  import { count } from "./stores.js";

  let countValue;

  const unsubscribe = count.subscribe(value => {
    countValue = value;
  });

  const increment = () => {
    count.update(n => n + 1);
  };

  const reset = () => {
    count.set(0);
  };
</script>

<button on:click={increment}>Increment</button>
<button on:click={reset}>Reset</button>
<p>{countValue}</p>
```

In the code above, we run `count.set(0)` when we click on Reset to set the `count` state to 0.

We have to call `unsubscribe` on the store when the component is destroyed so that we can free up the resources used for the subscription of states.

For instance, we can modify the example above as follows to do that:

`App.svelte` :

```
<script>
  import { count } from "./stores.js";
  import { onDestroy } from "svelte";

  let countValue;

  const unsubscribe = count.subscribe(value => {
    countValue = value;
  });

  const increment = () => {
    count.update(n => n + 1);
  };

  onDestroy(unsubscribe);
</script>

<button on:click={increment}>Increment</button>
<p>{countValue}</p>
```

The code above calls `unsubscribe` the function in the `destroy` portion of the component lifecycle so that the `count` state is no longer subscribed to.

We can replace the store state subscription with the `$` . For instance, we can shorten the above example to:

```
<script>
  import { count } from "./stores.js";
  import { onDestroy } from "svelte";

  const increment = () => {
    count.update(n => n + 1);
  };
</script>

<button on:click={increment}>Increment</button>
<p>{$count}</p>
```

We eliminated the code to subscribe and unsubscribe from the `count` store and the component still works the same as before.

### Read Only Stores

We can make a store that’s read only with the `readable` function.

For instance, we can write the following code to make a counter state that’s subscribed to by a component as follows:

`stores.js` :

```
import { readable } from "svelte/store";

export const count = readable(0, set => {
  let count = 0;
  const interval = setInterval(() => {
    set(count);
    count++;
  }, 1000);

  return () => {
    clearInterval(interval);
  };
});
```

`App.svelte` :

```
<script>
  import { count } from "./stores.js";
</script>

<p>{$count}</p>
```

In the code above, we call the `readable` function in the store. In the second argument, we pass in a callback with the `set` function as the parameter, which is called to update the store’s value.

We did that in the `setInterval` callback. Then we return another function, which is used to clean up the code when the store is unsubscribed to.

When we run the code, we see a number that’s incremented by 1 every second on the screen.

### Store with Derived State

We can call the `derived` function to create a store that’s derived from another state.

For instance, we can create a store that emits a value that’s double the `count` state that we have above as follows:

`stores.js` :

```
import { readable, derived } from "svelte/store";

export const count = readable(0, set => {
  let count = 0;
  const interval = setInterval(() => {
    set(count);
    count++;
  }, 1000);

  return () => {
    clearInterval(interval);
  };
});

export const doubleCount = derived(count, $count => $count * 2);
```

`App.svelte` :

```
<script>
  import { count, doubleCount } from "./stores.js";
</script>

<p>{$count}</p>
<p>{$doubleCount}</p>
```

In the code above, we have the `doubleCount` store, which is created by calling the `derived` function with the `count` store passed in as the first argument and a callback which returns a value that we want to derive from the value emitted by `count` as the second argument.

Then we see a number that’s incremented by 1 every second and another that’s incremented by 2 every second.

### Store Bindings

We can bind directly to the value of the store if the store is writable.

For instance, we can use `bind:value` to bind to the store to the inputted value directly and manipulate the store’s value as follows:

`store.js` :

```
import { writable } from "svelte/store";

export const name = writable("");
```

`App.svelte` :

```
<script>
  import { name } from "./stores.js";
</script>

<input bind:value={$name}>
<button on:click="{() => $name += '.'}">
  Add period
</button>
<p>{$name}</p>
```

In the code above, we change the value of `$name` as we type in something in the input, and also when we click Add period.

Then we display the `$name` store’s value in the p element.

### Conclusion

A store is handy for storing shared states. We make stores that are read-only, writable or are derived from another store.