Store is open sign

State management in Svelte

No Comments

In 2020, web development is not only based on component-driven approaches but also on the use of state management solutions. These solutions are usually oriented towards the Flux architecture and its most prominent representative, Redux. That’s why it is not surprising that Svelte also brings a suitable solution here, which I present in the following article. The code shown here is taken from the official tutorial.

Interested in Svelte basics first? Have a look at my introduction to Svelte.

First steps

Svelte comes with its own store implementation, as already mentioned. If we want to implement a store that manages the state of a counter, for example, we only need two lines of code:

import { writable } from 'svelte/store';
 
export const count = writable(0);

The store is implemented as writeable (we will get to the read-only counterpart later) and we create a store with the initial state (here 0). The count variable exported here offers three methods:

  • subscribe(callback): executed when the store is updated. The callback function gets the initial value in the store as parameter
  • update(callback): executes the callback. The callback function gets the initial value in the store as parameter
  • set(value): sets the value in the store to the transferred value value

In a Svelte component a counter could look like this:

<script>
 import { count } from "./store";
 
 let count_value;
 function increment() {
   count.update(n => n + 1);
 }
 function decrement() {
   count.update(n => n - 1);
 }
 function reset() {
   count.set(0);
 }
count.subscribe(value => {
   count_value = value;
 });
</script>
 
<h1>The count is {count_value}</h1>
<button on:click="{increment}">
 +
</button>
<button on:click="{decrement}">
 -
</button>
<button on:click="{reset}">
 Reset
</button>

You can save the usage of the subscribe function by using the short form $count:

<script>
 import { count } from "./store";
 
 function increment() {
   count.update(n => n + 1);
 }
 function decrement() {
   count.update(n => n - 1);
 }
 function reset() {
   count.set(0);
 }
</script>
 
<h1>The count is {$count}</h1>
<button on:click="{increment}">
 +
</button>
<button on:click="{decrement}">
 -
</button>
<button on:click="{reset}">
 Reset
</button>

The $ character is a reserved character in Svelte, which must always refer to a store. So it is not allowed to use it for your own variables.

Custom stores

Now you do not always want to interact directly with the store within a component. In Redux there are Reducers and Actions, with which you can trigger changes to the state. In Svelte we can create a custom store, for which we can define our own operations. The advantage here is that you need less boilerplate code to manipulate the state.

import { writable } from "svelte/store";
 
function createCount() {
 const { subscribe, set, update } = writable(0);
 
 return {
   subscribe,
   increment: () => update(n => n + 1),
   decrement: () => update(n => n - 1),
   reset: () => set(0)
 };
}
 
export const count = createCount();

In the component we save a lot of code and make everything a bit clearer:

<script>
 import { count } from "./store";
</script>
 
<h1>The count is {$count}</h1>
<button on:click="{count.increment}">
 +
</button>
<button on:click="{count.decrement}">
 -
</button>
<button on:click="{count.reset}">
 Reset
</button>

Readable and derived store

In addition to the writeable store, Svelte offers two more appealing options: the readable store and the derived store.

The readable store is, as the name suggests, a read-only store. It can be used if the data managed in the store should not be manipulated by the user.

The derived store allows you to manage data dependent on other stores. This way, complexity in individual stores can be avoided by outsourcing them to derived stores.

Conclusion

Svelte is not reinventing the wheel when it comes to state management: We are already familiar with the idea of implementing state management via stores from React, Angular and Vue. Nevertheless, the solution established by Svelte is interesting: read-only and derived stores solve known problems in front-end applications. The possibility to create custom stores saves a lot of boilerplate code (which can be replaced by libraries) and allows you to implement the stores with domain-specific logic.

Picture by Mike Petrucci

Daniel Mies

Daniel is part of the codecentric team as a IT-Consultant since 2015. He likes to work in backend as well as in the frontend.

Currently his focus lies on IoT and Industry4.0 where he supports companies as product owner in their projects.

Comment

Your email address will not be published. Required fields are marked *