更新Svelte writable对象store时能否直接进行突变操作?
Svelte Writable Store 对象突变问题解答
结论:语法上能运行,但绝对不推荐,十有八九会踩坑
你这段代码写出来不会报错,但Svelte的store是靠引用变化触发组件更新的。你直接修改prev的属性后返回同一个对象引用,Svelte会判定数据没有变化,根本不会通知订阅该store的组件刷新,最后就会出现数据改了但界面没同步的问题。
你有Redux背景应该清楚,Redux要求不可变更新是因为它依赖新旧状态的对比来触发更新;Svelte虽然没强制要求不可变,但store的更新逻辑同样需要返回新引用,才能让框架感知到数据变化。
正确的几种写法
1. 手动生成新对象(基础场景首选)
myStore.update((prev) => { return { ...prev, // 复制原有所有属性 a: prev.a + 1 // 只修改需要更新的属性 }; });
2. 用Immer简化复杂对象更新
如果你的对象结构比较复杂,不想手动写展开运算符,可以用Immer,写法和Redux里完全一致:
import { produce } from 'immer'; myStore.update((prev) => { return produce(prev, (draft) => { draft.a++; // 直接修改draft,Immer自动帮你生成新对象 }); });
3. 直接用set方法(知道完整新状态时用)
如果能直接拿到完整的新对象,也可以直接调用set方法:
myStore.set({ a: 2, b: 2 });
额外提醒
不管是组件内的响应式变量还是store,Svelte的响应式本质都是靠跟踪引用变化实现的。所以哪怕你能直接修改对象,也一定要保证更新后返回新的引用,否则响应式逻辑就会失效。
内容的提问来源于stack exchange,提问作者ZYinMD
相关产品推荐
相关产品推荐

