Svelte 自定义商店让我们可以直接修改状态

问题描述 投票:0回答:1

下面我有一个在 Svelte 中创建的自定义商店。第一个按钮

Add item
调用
addItem()
将按预期将新项目添加到状态。点击第二个按钮
Add item to object directly
也会更新状态!如何阻止这种情况发生并仅允许通过
addItem()
修改状态?

重现步骤:

  • 点击
    Add item
    按钮(我们可以看到新的项目渲染)
  • 点击
    Add item to object directly
    (我们可以看到控制台错误
    Error: store.set is not a function
    ,我们看不到项目渲染)
  • 点击
    Add item
    按钮(现在我们将看到 three 项目而不是 two 项目,因为之前的点击直接修改了状态)
<script>
    import { writable } from 'svelte/store';
    
    function itemStore() {
        const { subscribe, update } = writable({ items: [], name: 'test' });

        return {
            subscribe,
            addItem: () => update(n => ({ ...n, items: [...n.items, new Date().valueOf()] })),
        };
    }
    
    const store = itemStore()
</script>

<h1>The count is {$store.items.length}</h1>

{#each $store.items as i}
    <div>{i}</div>
{/each}

<button on:click={store.addItem}>Add item</button>
<br>
<button on:click={() => { $store.items = [...$store.items, new Date().valueOf()+' - added directly'] }}>Add item to object directly</button>
svelte immutability svelte-store
1个回答
0
投票

$store.items = ...
这样的操作先改变值,然后触发一个store
set
,store的设置失败,但是对象还是被修改了

您可以通过冻结存储中的对象,使其不可变来防止这种情况。

function itemStore() {
    const { subscribe, update } = writable(Object.freeze({
      items: [],
      name: 'test',
    }));

    return {
        subscribe,
        addItem: () => update(n => Object.freeze({
          ...n,
          items: [...n.items, new Date().valueOf()],
        })),
    };
}
© www.soinside.com 2019 - 2024. All rights reserved.