当函数返回的值在模板上更改时,SVELTE 调用 await 函数

SVELTE calling await function when value returned by function changes on template

我不明白为什么 SVELTE 在函数返回的值发生变化时调用 {#await} 块中指定的函数。

我举了一个小例子:

https://svelte.dev/repl/a962314974eb4a07bd98ecb1c9ccb66c?version=3.35.0

简述:

{#await getList() then alist}
    {#each alist as item}
    <div>
        {item.state}
        <div class="button" on:click={()=>item.state=!item.state}>Toggle it!</div>
    </div>
    {/each}
{/await}

每次单击“按钮”div 以切换函数返回的对象的值时,都会调用函数 getList()。我不明白为什么。

谁能赐教一下?

谢谢!

我认为这是因为当状态改变时整个组件被重新渲染,因此 getList() 在渲染代码中被再次调用。

更好的解决方案可能是找到如何避免使用 immutable 的整个重新渲染,但这里有一种方法可以实现此目的:

<script>
    let list = [
        { state: true}, { state: true}, { state: true},{ state: true}
    ]
    let counter = 0;
    async function getList(){
        counter++;
        return Promise.resolve(list);
    }
    const promise = getList()
</script>

Times GetList called: {counter}

{#await promise then alist}
    {#each alist as item}
    <div>
        {item.state}
        <div class="button" on:click={()=>item.state=!item.state}>Toggle it!</div>
    </div>
    {/each}
{/await}

状态更改不会(通常)导致整个组件重新渲染,毕竟这是 Svelte 的基本原则。您可以通过在 await:

中添加第二个计数器和一个按钮来尝试此操作
{#await getList() then alist}
  <button on:click={() => counter2++}>Clicked {counter2}</button>
  ...

单击此按钮将增加 counter2 而不会再次触发 getList

这里的问题似乎是由于您正在直接编辑异步操作的结果,从而以某种方式重新触发了上述操作。考虑到其他答案有效,这一定与函数调用有关。

解决此问题的另一种方法是将每个循环的内部结构移动到它自己的组件中:

{#await getList() then alist}
  {#each alist as item}
    <Child {...item} />
  {/each}
{/await}