下面我有一个在 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>
像
$store.items = ...
这样的操作先改变值,然后触发一个storeset
,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()],
})),
};
}