【问题标题】:How to update this Svelte store without recreate it every time?如何更新这个 Svelte 商店而不每次都重新创建它?
【发布时间】:2021-10-16 19:23:10
【问题描述】:

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

代码如下:

App.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}

store.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 };
};

如您所见,如果您点击“更改名称”,商店就会重新创建。

这是我需要避免的。

但是怎么做呢?

【问题讨论】:

标签: javascript svelte svelte-3 svelte-component svelte-store


【解决方案1】:

尽量像在./store.js 文件中那样实例化您的商店,然后使用setupdate 方法而不是直接在组件中实例化它:

// store.js

import {writable} from "svelte/store";

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

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

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

    return { subscribe, set, update };
};

export const player = createEditableStore()
<!-- App.svelte -->

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

    $: player.update(p => ({ ...p, 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}

看看REPL

【讨论】:

    【解决方案2】:

    不要在每次name 更改时重新创建商店,而是只创建一次并在name 更改时设置$player.name

    <script>
        import {editableStore} from "./store";
        
        let name = "John";
    
        let player = editableStore(name);
        $: $player.name = name;
    </script>
    

    这将要求您更新存储方法以返回 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 };
    };
    

    【讨论】:

      猜你喜欢
      • 2021-02-27
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多