我有一个带有自定义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
?
谢谢ï¼
ç”案 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
)。对我æ¥è¯´ï¼Œè¿™æœ‰ç‚¹å‡ºä¹Žæ„料,而且å¯èƒ½æ˜¯ä¸€ä¸ªå¾ˆä¸¥é‡çš„错误。至少,当我们设计å¤æ‚的定制商店并希望使用商店的简写时,需è¦ç‰¢è®°è¿™ä¸€ç‚¹ã€‚