Svelte存储分配调用默认writable().set,然后调用custom.set



相关REPL

我有一个简单的可写存储,带有自定义set方法:

import { writable } from 'svelte/store';
function createState() {
const {subscribe, set, update} = writable({a: 0, b: 0});
return {
subscribe,
set: (newState) => {
console.log(newState);
// set(newState); // I would expect `state` to be unchanged without this
}
};
};
export const state = createState();

当我调用state.set(<some new value>)时,新值会记录到控制台中,而state的值实际上不会更改。这就是我所期望的
但是,如果我分配$state = <some new value>,则state的值会更改,set会将其记录到控制台。为什么(以及如何(发生这种情况,有没有一种方法可以绕过它而不重新实现writable

谢谢!

这是预期行为!暂时忘记存储,并且——由于state.set在您的示例中是一个noop——删除这一行:

<script>
// import { state } from "./stores.js";
let pojo = { a: 0, b: 0 };
pojo.a = 1;
pojo = {d: 0};
//state.set({c: 0}); // no effect, as expected
</script>
<h1>state: {JSON.stringify(pojo)}</h1> 

结果。。。

state: {"d":0}

。。。正是你所期望的。

当我们用$state替换pojo时,我们仍然在分配(或突变(一个具有相同反应特性的局部变量。唯一的区别是,我们调用state.set。通常情况下,这会导致存储值发生变化,并反映给其订阅者,但由于您的自定义存储不会这样做,因此我们只剩下最后一次赋值运算符触摸$state之后的值。

在REPL的JS输出中,您可以看到以下内容:

function instance($$self, $$props, $$invalidate) {
let $state;
component_subscribe($$self, state, $$value => $$invalidate(0, $state = $$value));
set_store_value(state, $state.a = 1, $state); // changes the value of state?!
set_store_value(state, $state = { d: 0 }); // ''
state.set({ c: 0 }); // no effect, as expected
return [$state];
}

使用简写的反应式分配$<store>编译成set_store_value()调用,这是一个如此定义的苗条内部方法:

export function set_store_value(store, ret, value = ret) {
store.set(value);
return ret;
}

因此,正如您所期望的那样,分配的值实际上被传递给了商店的set函数。

但是,您可以在上面的JS输出中看到,最终返回的值是一个名为$state局部变量(这里的$符号是,而不是反应修饰符,只是名称的一部分(。在这些set_store_value()调用过程中,您可以看到这个局部变量被分配了与传递给商店的set方法的值相同的值(事实上,局部变量被指定了该值,然后自身被传递给set_store_value()方法(:

set_store_value(state, $state.a = 1, $state); // changes the value of state?!
set_store_value(state, $state = { d: 0 }); // ''

我希望这种行为是某种乐观的展望/解决方案。

也许Svelte商店合同中暗示,传递给商店的set方法的值实际上必须相应地修改商店,在这种情况下,乐观解析方法总是会产生一致的结果?

希望Rich Harris(或另一位Svelte撰稿人(能看到你的问题,并提供更明确的答案。

扩展Thomas Hennes的伟大分析:

set_store_value(state, $state.a = 1, $state);

该内部调用在不使用setupdate方法的情况下更新内部存储模型($state.a = 1(。对我来说,这有点出乎意料,可能是一个苗条的bug。至少,当我们设计复杂的定制商店并想使用商店人手不足时,我们需要记住这一点。

相关内容

  • 没有找到相关文章

最新更新