如何更新这个 Svelte 商店而不每次都重新创建它?

Fre*_*ors 1 javascript svelte svelte-component svelte-store svelte-3

这里是 REPL:https://svelte.dev/repl/56770fec88af4b76bdc8ea962178854e ?version=3.42.1

这里是代码:

应用程序.svelte:

<script>
    import {editableStore} from "./store";
    
    let name = "John"

    $: player = editableStore(name);
</script>

<h1>Hello {$player.name}!</h1>

<button on:click={() => name = (name === "Bob" ? "Jerry" : "Bob")}>
    Change name
</button>

<h2>Log:</h2>

{#each $player.log as log}
    <li>{log}</li>
{/each}
Run Code Online (Sandbox Code Playgroud)

商店.js:

import {writable} from "svelte/store";

const defaultStore = {
    name: "Bob",
    age: 18,
    log: []
};

export const editableStore = (name) => {
    console.log("Recreated with name:", name);

    const {subscribe, update} = writable({...defaultStore}, () => () => clearInterval);

    if (name) {
        update(s => ({...s, name}));
    }

    const clearInterval = setInterval(() => {
        update(s => ({...s, log: [...s.log, new Date()]}))
    }, 1000)

    return { subscribe };
};
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,如果您单击“更改名称”,则会重新创建商店。

这是我需要避免的。

但如何呢?

Geo*_*ich 7

不必在每次更改时重新创建存储name,只需创建一次并在更改$player.name时进行设置name

<script>
    import {editableStore} from "./store";
    
    let name = "John";

    let player = editableStore(name);
    $: $player.name = name;
</script>
Run Code Online (Sandbox Code Playgroud)

这将需要您更新存储方法以返回该set函数。

export const editableStore = (name) => {
    console.log("Recreated with name:", name);

    // also destructure set here
    const {subscribe, update, set} = writable({...defaultStore}, () => () => clearInterval);

    if (name) {
        update(s => ({...s, name}));
    }

    const clearInterval = setInterval(() => {
        update(s => ({...s, log: [...s.log, new Date()]}))
    }, 1000)

    // also return set here
    return { subscribe, set };
};
Run Code Online (Sandbox Code Playgroud)