What are readable stores in Svelte and how can you use them?
Published
Most of the time, you will be using or dealing with regular writable stores when writing an app with Svelte. But sometimes you’ll want a store that can’t be written to but whose value can only be consumed. That’s when you want to make your svelte store readable.
Why not just use a writable store?
While you could just use a writable store and use it the same way you would a readable one, resorting to a readable store gives you the guarantee that:
- The store is responsible for its own data
- No outside code can affect the store’s data
Being more restrictive is generally a good idea, especially once you start working on a project with multiple other developers. It’s a cheap and easy way to signal that this store’s state is meant to be pure.
How can I write a readable store?
Setting up a readable store is a bit more involved than a writable store as it needs to encompass the logic it needs to compute its own data.
We’ll be writing a readable store that sets up and removes an event listener in order to provide the user’s mouse position. As usual with Svelte, the logic is written using plain and simple Javascript so it’s pretty easy to follow along.
<script>
import { onMount } from 'svelte';
import { readable } from 'svelte/store';
// We're declaring the store
let store;
// We'll be accessing the window object, so we need to ensure the component is actually mounted
onMount(() => {
store = readable({ x: 0, y: 0 }, (set) => {
// let's get the user's mouse position through an event listener
window.addEventListener('mousemove', (event) => {
set({ x: event.clientX, y: event.clientY });
});
// Let's not forget to clean up once we're done
return () => window.removeEventListener('mouvemove');
});
});
</script>
<!-- store is undefined at first -->
{#if store}
<div>
x: {$store.x}
y: {$store.y}
</div>
{/if}
You’ll notice that we’re returning a function from the readable function. This function will be called when the store goes out of scope and gets destroyed. You will want to put your cleaning code in it. Here we’re removing the “mousemove” event listener so it doesn’t overstay its welcome.