【问题标题】:svelte update with no change always triggers re-render没有变化的苗条更新总是触发重新渲染
【发布时间】:2021-01-30 14:10:34
【问题描述】:

我一直在玩 svelte,但我很难管理渲染。

我注意到,每当调用 store 的 update 方法时,都会触发重新渲染,即使 store 没有更改。我想我可能做错了什么,但我不确定是什么。

这是一个简单的例子。我原以为单击按钮不会在控制台中显示任何内容,因为没有实际更改(例如 Redux),但我每次都会收到一条新消息。

App.svelte:

{#each $store as value}
    {value}
{/each}
<button on:click={updateStore} type="button">Click me</button>

<script>
    import { afterUpdate } from 'svelte'
    import { store, updateStore } from './store.js'
    
    afterUpdate(() => console.log('render'))
</script>

store.js:

import { writable } from 'svelte/store'

export const store = writable([])

export const updateStore = () => store.update(s => s)

这是一个问题吗?我应该在我的控制台中显示这些消息,还是应该添加类似get(store) 的内容来决定是否要实际调用update

【问题讨论】:

    标签: svelte


    【解决方案1】:

    Svelte 生成的代码对 store 的值一无所知,无论是否更改,它都会在每次 store 更新发生时呈现。为了实现你想要的,你必须用你自己的实现包装writable,它检查对象引用是否改变,并取决于它是否发出事件。粗略的实现:

    export function customWritable (value, start) {
       const _writable = writable(value, start);
       const set = (newVal) => {
         if (newVal !== value) {
           value = newVal;
           _writable.set(newVal);
         }
       };
       const update = (updateFn) => {
          set(updateFn(value));
       };
       
       return { set, update, subscribe: _writable.subscribe };
    }
    

    【讨论】:

    • 太棒了,感谢详细的解释!
    猜你喜欢
    • 2020-08-18
    • 2017-01-15
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 2018-02-28
    相关资源
    最近更新 更多