We’re familiar with React Redux, or Vue’s Vuex, both of which come in packages. For complex state control, there may be specialized libraries like MOBx or RXJS.
State management is still a very useful feature when you want to be able to access a state from anywhere outside of the hierarchy of components, especially when some state needs to be accessed by multiple unrelated components or ordinary JavaScript modules.
Svelte basically divides states into two types, those that can be read and written and those that can only be read. The writable state is the most commonly used state, while the read-only state readable is used to prevent accidental changes.
We can put the code to create the state in a separate file store.js, so that other components that need to use the corresponding state can be introduced and used to facilitate unified management and maintenance.
Writable Stores
// The writable state introduces svelte/store
import { writable } from 'svelte/store';
const count = writable(0); Store 0 is the value stored by store
Copy the code
In Svelte, a store (or state) is just a normal object with a subscribe method,
You can think of an object as a store as long as it implements subscribe correctly
It allows you to automatically push notifications to all subscribe subscribers who subscribe when the value of the store changes.
letCount_value;// count is a store
// subscribe the count_value callback automatically subscribes to count
// This callback is automatically called when the component is initialized and the count value changes to update count_value to the latest count value
count.subscribe(value= > {
count_value = value;
});
Copy the code
<script>
import { onDestroy } from 'svelte';
import { count } from './stores.js';
import Incrementer from './Incrementer.svelte';
import Decrementer from './Decrementer.svelte';
import Reset from './Reset.svelte';
let count_value;
// subscribe returns a function that is used to unsubscribe
// Avoid memory leaks when the component is instantiated and destroyed multiple times
const unsubscribe = count.subscribe(value= > {
count_value = value;
});
onDestroy(unsubscribe);
</script>
<h1>Count is currently {count_value}.</h1>
Copy the code
When a store is a writable store, it means that it has set and update methods in addition to subscribe.
// Update the store value based on the original store value
count.update(n= > n + 1);
// Set the store value to a new value
count.set(0);
Copy the code
Auto-subscriptions
Count. Subscribe is tedious to write and requires manual unsubscription in onDestory.
If you use a lot of stores, the code will look dull and repetitive.
Svelte provides the corresponding syntactic sugar, prefixing the store name with $to refer to the store value.
So Svelte assumes that any identifier beginning with $refers to a store value, and that $is actually a reserved character,
Svelte disallows you to prefix your declared variables with $.
<script>
import { count } from './stores.js';
</script>
<h1>The current value of count is {$count}</h1>
Copy the code
Read-only state (Readable Stores)
Not all stores allow anyone to write.
There may be a store that stores user information or tokens that need to be sent to the server for access tokens, etc. Changing this value is meaningless.
Readable has two parameters
// Parameter 1: the initial value of store. If not, it can be set to null or undefined
This callback takes a set callback to set the value and returns a stop function.
// The start function is called when the store is read by the first subscriber
// The stop function is called when the last subscriber unsubscribes.
The second parameter can be omitted if the store does not need to be updated internally
export const time = readable(new Date(), function start(set) {
// Every 1s, change time to the current time, meaning that the read-only store is not immutable
// If you want to change the value of read-only store, you can only do it through a predefined callback
// A variable subscribed externally to a store value cannot modify the read-only store value from 'externally'
const interval = setInterval(() = > set(new Date()), 1000);
return function stop() { clearInterval(interval); };
});
Copy the code
State Inheritance (Derived Stores)
You can call Derived to create a new store that inherits from one or more other stores
<script>
import {writable, derived} from 'svelte/store';
// Define a modifiable store
let num = writable(0)
// Double is derived from num, and when num changes it automatically gets a new value according to preset rules
// The store for the dispatch process is a readable Store
let double = derived(
num, $num = $num
$num => $num * 2
)
setInterval(() = > $num+=1.1000)
</script>
<h1>num = {$num}</h1>
<h1>double = {$double}</h1>
Copy the code
<script>
import {writable, derived} from 'svelte/store';
let num1 = writable(0)
let num2 = writable(2)
// Can be derived from multiple stores to a single store
let sum = derived(
[num1, num2], // Multiple stores are passed in as arrays
$nums => $nums[0] + $nums[1])setInterval(() = > {
$num1 += 1
$num2 *= 2
}, 1000)
</script>
<h1>num1 = {$num1}</h1>
<h1>num2 = {$num2}</h1>
<h1>sum = {$sum}</h1>
Copy the code
Custom States (Custom Stores)
In daily development, it is common to write states to separate JS files, such as one JS file per state
Encapsulate operations related to a state and export them uniformly to avoid exposing the SET and UPDATE methods and the corresponding update logic
Custom state gives us the opportunity to encapsulate a state that is closer to the business and easier to use
function createCount() {
const { subscribe, set, update } = writable(0);
return {
subscribe,
increment: () = > update(n= > n + 1),
decrement: () = > update(n= > n - 1),
reset: () = > set(0)}; }Copy the code
State Bindings
In Svelte, the binding and use of state in templates is not much different from regular data
<input bind:value={$name}>
<button on:click="{() => $name += '! '}">
Add exclamation mark!
</button>
Copy the code