这是 Svelte 中 Array push() 的问题还是我做错了什么?
Is this a problem with Array push() in Svelte or is it something I'm doing wrong?
我已经为这个问题绞尽脑汁好几个小时了,尽管我找到了解决该问题的方法,但我还是无法忘记它正在发生的事实。我不明白。在承诺处理程序中使用 Array.push() 似乎存在某种问题。我创建了下面的测试代码来演示它,它可以在 Svelte REPL 中重现。我只是做错了什么吗?
<script>
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('foo');
}, 300);
});
let itemsA = [];
let itemsB = [];
const addItem = (item) => {
itemsA[itemsA.length] = item;
itemsB.push(item);
}
const loadItems = (last) => {
addItem("Begin");
myPromise
.then((value) => {
addItem(value);
});
addItem("End");
return true;
};
loadItems();
</script>
<div>Items A: {itemsA}</div>
<div>Items B: {itemsB}</div>
我认为 itemsB.push(item) 应该和 itemsA[itemsA.length] = item 做同样的事情,而且确实如此,除非从 promise 处理程序内部调用。
我得到以下结果:
Items A: Begin,End,foo
Items B: Begin,End
编辑:我已经消除了 promises 作为奇怪的来源。下面的代码更简单地说明了它。
<script>
let itemsA = [];
let itemsB = [];
const addItem = (item) => {
itemsA[itemsA.length] = item;
itemsB.push(item);
}
const clickHandler = () => {
addItem('click');
}
addItem('load');
</script>
<div>Items A: {itemsA}</div>
<div>Items B: {itemsB}</div>
<button on:click={clickHandler}>Click Me</button>
其实这与承诺无关。当您添加一个按钮并记录数组时,您会看到 'foo' 也在 'itemsB' 中,只是没有呈现。
来自 Svelte 文档
Because Svelte's reactivity is based on assignments, using array methods like .push() and .splice() won't automatically trigger updates. A subsequent assignment is required to trigger the update.
The according tutorial
您可以使用 .push(),如果它之后是将数组重新分配给自身
itemsB.push(item);
itemsB = itemsB
或者使用扩展运算符语法
itemsB = [...itemsB, item]
这里有一个 REPL 来试试这个
我已经为这个问题绞尽脑汁好几个小时了,尽管我找到了解决该问题的方法,但我还是无法忘记它正在发生的事实。我不明白。在承诺处理程序中使用 Array.push() 似乎存在某种问题。我创建了下面的测试代码来演示它,它可以在 Svelte REPL 中重现。我只是做错了什么吗?
<script>
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('foo');
}, 300);
});
let itemsA = [];
let itemsB = [];
const addItem = (item) => {
itemsA[itemsA.length] = item;
itemsB.push(item);
}
const loadItems = (last) => {
addItem("Begin");
myPromise
.then((value) => {
addItem(value);
});
addItem("End");
return true;
};
loadItems();
</script>
<div>Items A: {itemsA}</div>
<div>Items B: {itemsB}</div>
我认为 itemsB.push(item) 应该和 itemsA[itemsA.length] = item 做同样的事情,而且确实如此,除非从 promise 处理程序内部调用。
我得到以下结果:
Items A: Begin,End,foo
Items B: Begin,End
编辑:我已经消除了 promises 作为奇怪的来源。下面的代码更简单地说明了它。
<script>
let itemsA = [];
let itemsB = [];
const addItem = (item) => {
itemsA[itemsA.length] = item;
itemsB.push(item);
}
const clickHandler = () => {
addItem('click');
}
addItem('load');
</script>
<div>Items A: {itemsA}</div>
<div>Items B: {itemsB}</div>
<button on:click={clickHandler}>Click Me</button>
其实这与承诺无关。当您添加一个按钮并记录数组时,您会看到 'foo' 也在 'itemsB' 中,只是没有呈现。 来自 Svelte 文档
Because Svelte's reactivity is based on assignments, using array methods like .push() and .splice() won't automatically trigger updates. A subsequent assignment is required to trigger the update.
The according tutorial
您可以使用 .push(),如果它之后是将数组重新分配给自身
itemsB.push(item);
itemsB = itemsB
或者使用扩展运算符语法
itemsB = [...itemsB, item]
这里有一个 REPL 来试试这个