è‹—æ¡çš„商店分é…调用默认的writable()。set,然åŽè‡ªå®šä¹‰.set?

时间:2020-07-22 06:02:32

标签: svelte svelte-3 svelte-store

Relevant 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çš„å€¼ä¼šæ›´æ”¹ï¼Œç„¶åŽ then set会将其记录到控制å°ã€‚为什么(以åŠå¦‚何)å‘生这ç§æƒ…况,并且有办法解决而ä¸é‡æ–°å®žçŽ°writable?

谢谢ï¼

3 个答案:

答案 0 :(得分:4)

这是预期的行为ï¼æš‚时忘掉商店,并且-因为state.set在您的示例中是个å°é—®é¢˜-删除该行:

<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}

...正是您所期望的。

当我们将pojo替æ¢ä¸º$state时,我们ä»å°†åˆ†é…(或å˜å¼‚)具有相åŒå应性特å¾çš„局部å˜é‡ã€‚唯一的区别是我们也正在调用state.set。通常,这将导致商店价值å‘生å˜åŒ–,并å映给其订户,但是由于您的自定义商店没有这样åšï¼Œå› æ­¤å‰©ä¸‹çš„是上次$state被分é…触åŠä¹‹åŽçš„价值è¿ç®—符。

答案 1 :(得分:3)

在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()调用,这是thusly定义的一ç§ç²¾å·§çš„内部方法:

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

因此,分é…的值实际上将按照您的期望传递给商店的set函数。

但是,您å¯ä»¥åœ¨ä¸Šé¢çš„JS输出中看到,最终返回的值是å为$state($符å·çš„ local å˜é‡æ²¡æœ‰ä¸æ˜¯å应å¼ä¿®é¥°ç¬¦ï¼Œåªæ˜¯å称的一部分)。在这些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 store contract中暗示,传递给商店的set方法的值必须实际上必须相应地修改商店,在这ç§æƒ…况下,ä¹è§‚解决方法将总是产生连贯的结果?

希望里奇·哈里斯(或其他斯维尔特撰稿人)看到您的问题并æ供更明确的答案。

答案 2 :(得分:1)

扩展Thomas Hennes的出色分æžï¼š

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

此内部调用无需使用$state.a = 1或set方法å³å¯æ›´æ–°å†…部商店模型(update)。对我æ¥è¯´ï¼Œè¿™æœ‰ç‚¹å‡ºä¹Žæ„料,而且å¯èƒ½æ˜¯ä¸€ä¸ªå¾ˆä¸¥é‡çš„错误。至少,当我们设计å¤æ‚的定制商店并希望使用商店的简写时,需è¦ç‰¢è®°è¿™ä¸€ç‚¹ã€‚