If you’re familiar with Redux or Vuex, then the Svelte stores offer a similar feature for state management. If your app is getting complicated, then it becomes difficult for components to relay data between themselves. Moving it to a global data store is a better option. Here, we’ll look at two store options that Svelte makes available: writable stores and readable stores.
Let’s go ahead and create a global state management file in our Svelte project - let’s call it store.js
and import the writable
function.
import { writable } from "svelte/store";
let counter = writable(1);
export {counter}
We’ve created a variable called counter
, which is a writable store. counter
now has the following self-explanatory methods:
set
update
Let’s create a custom component called Nested.svelte
and use the counter
store we just created.
<script>
import { counter } from "./store.js";
</script>
<div>
counter value: {$counter}
</div>
Notice that during usage, we prefix the the variable with $
, since this is a named import.
Let’s wrap it up by importing the component in the App.svelte
file and create a method to write the counter
variable to observe reactivity across nested components.
<script>
import Nested from "./Nested.svelte";
import { counter } from "./store.js";
function incrementCounter() {
counter.update(n => n + 1);
}
</script>
<div>
<button on:click={incrementCounter}>Update</button>
<Nested />
</div>
the counter
uses an update
method that takes a function whose parameter is the current value of the writable store and returns the modified value. If we run this app, we should be able to see the value inside the Nested
component getting updated as we click on the button.
While we’re at it, let’s go ahead and add a reset
button to App.svelte
.
function resetCounter() {
counter.set(1);
}
<button on:click={resetCounter}>Reset</button>
The resetCounter
uses the set
method of our writable store.
Now, the writable
function also supports a second argument which is also a function. Here’s the signature for that function:
writable(value: any, (set: (value: any) => void) => () => void)
This function is fired when the first subscriber is created and it returns another function that is fired when the last subscription to the variable is destroyed. Let’s see that in action.
In our store.js
, add the second argument to the writable function:
let counter = writable(1, () => {
console.log("First subscriber added!");
return () => {
console.log("Last subscriber deleted :(");
};
});
To test this, we’ll mount and unmount the Nested
component to observe the behavior, in App.svelte
:
<script>
// ...
let flag = false;
function toggleMount() {
flag = !flag;
}
</script>
<!-- ... -->
<button on:click={toggleMount}>Mount/Unmount</button>
{#if flag}
<Nested />
{/if}
</div>
Svelte also offers the readable
function, which allows for creating readable stores whose values cannot be updated from other components. The value has to set
from within the store. Let’s try this out, modify the store.js
-
import { readable } from "svelte/store";
let initialVal = Math.floor(Math.random()*100);
let counter = readable(initialVal, (set) => {
let incrementCounter = setInterval( () => {
let newVal = Math.floor(Math.random()*100);
set(newVal);
}, 1000);
return () => {
clearInterval(incrementCounter);
};
});
export {counter}
Here the readable
counter is set with the initialVal
, which is being passed as the first argument. The second argument is the same as with writable stores, but this time it’s a required parameter since without it there would be no other way to access the counter
value to reset it.
In this example, we generate random numbers between 0 to 100 and assign this to counter
by using the set
method. update
is not available. This is a simple demo, but in real apps readable stores can use the second argument to make API calls and, based on some logic, set
the value. This will render the components that are subscribed to this store.
As you saw, by using writable
and readable
stores in Svelte, we can achieve a basic form of global state management pretty easily! ✨
Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.
Sign up