我有一个简单的状态对象,字符串 -> 对象。我的 UI 在循环中呈现键和值。每个对象都有一个删除按钮。单击时,我想删除键(或将它们设置为未定义),以便 UI 更新。
Svelte 教程中的此页面说:
一个简单的经验法则:更新的变量的名称必须出现在赋值的左侧。例如这个...
const obj = { foo: { bar: 1 } }; const foo = obj.foo; foo.bar = 2;
...不会触发 obj.foo.bar 上的反应,除非您使用 obj = obj 进行后续操作。
果然,如果我像这样处理点击:
{#each Object.entries(objInState) as [key, value]}
{value}
<button on:click={_ => delete objInState[key]}
{/each}
...页面行为异常并且不会立即更新。 (与设置为未定义相同。)
果然,当我将其更改为:
{#each Object.entries(objInState) as [key, value]}
{value}
<button on:click={_ => {
delete objInState[key]
objInState = objInState
}}
{/each}
...它有效。
但是它读起来非常丑陋且令人困惑。有没有更好的办法?
有一种构造新对象的模式需要赋值,因此总是会触发反应性(在 Svelte 3/4 中);这对于数组来说很常见:
array = array.filter(v => v != valueToDelete)
你可以在这里做类似的事情,但是对于对象来说它明显不太漂亮:
obj = Object.fromEntries(
Object.entries(obj).filter(([k]) => k != key)
)
(不过,可以将逻辑提取到函数中。)