Home >Web Front-end >JS Tutorial >Sharing Runes in Svelte ith the Rune Class

Sharing Runes in Svelte ith the Rune Class

DDD
DDDOriginal
2025-01-16 13:00:00381browse

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>
  • Repo Link (Please provide if available)
  • Demo Link (Please provide if available)

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn