Home >Web Front-end >JS Tutorial >Sharing Runes in Svelte ith the Rune Class
While I generally avoid classes in my TypeScript projects, favoring functions for their simplicity and tree-shaking benefits, using classes with Svelte's reactive $state
variables can offer performance advantages. Rich Harris himself suggests this approach in certain situations. The key is that classes bypass the compilation overhead associated with getters and setters for $state
variables.
A Sharable Rune Class
This requires a sharable Rune
class leveraging Svelte's context API.
<code class="language-typescript">// rune.svelte.ts import { getContext, hasContext, setContext } from "svelte"; type RCurrent<TValue> = { current: TValue }; export class Rune<TRune> { readonly #key: symbol; constructor(name: string) { this.#key = Symbol(name); } exists(): boolean { return hasContext(this.#key); } get(): RCurrent<TRune> { return getContext(this.#key); } init(value: TRune): RCurrent<TRune> { const _value = $state({ current: value }); // Assuming '$state' is available from a library like 'svelte-state' return setContext(this.#key, _value); } update(getter: () => TRune): void { const context = this.get(); $effect(() => { // Assuming '$effect' is available from a library like 'svelte-state' context.current = getter(); }); } }</code>
We can then export custom runes as needed:
<code class="language-typescript">// counter.svelte.ts import { Rune } from "./rune.svelte"; export const counter = new Rune<number>('counter');</code>
This method, while similar to common $state
sharing techniques, offers server-side compatibility (as discussed in previous posts). Context naming follows standard conventions.
Initialization
Initialization of the $state
variable happens only once, within the parent component:
<code class="language-svelte"><script> import { counter } from '$lib/counter.svelte'; const count = counter.init(0); </script></code>
Reading the Value
Child components can safely access and read the current value:
<code class="language-svelte"><script> import { counter } from '$lib/counter.svelte'; const count = counter.get(); </script> <h1>Hello from Child: {count.current}</h1> <button on:click={() => count.current++}>Increment From Child</button></code>
Reactive Updates
Updating the shared $state
requires a function to trigger reactivity:
<code class="language-svelte"><script> import { counter } from '$lib/counter.svelte'; let value = $state(8); // Assuming '$state' is available counter.update(() => value); </script></code>
This enables reactive updates, handling signals and store variables similarly to $derived
.
Direct Updates
Direct updates are also supported:
<code class="language-svelte"><script> import { counter } from '$lib/counter.svelte'; const count = counter.get(); count.current = 9; </script></code>
This approach provides a structured and performant way to manage shared reactive state in Svelte applications.
The above is the detailed content of Sharing Runes in Svelte ith the Rune Class. For more information, please follow other related articles on the PHP Chinese website!