【问题标题】:Reactive statement being executed when child reactive statement changes?子反应性语句更改时正在执行反应性语句?
【发布时间】:2020-04-21 19:27:44
【问题描述】:

我在 Svelte 中有两个反应式语句。当子语句发生变化(基于某些输入)时,父语句(子语句所依赖的语句)也会被触发。检查以下sn-p:

<script>
    const options = [
        {key: 'one'},
        {key: 'two'},
        {key: 'three'},
    ];

    // NOTE: initialOption may be obtained reactively from somewhere like the query string.
    $: initialOption = options[0];
    $: selectedOption = initialOption;

    $: console.log('initialOption reactivity:', initialOption);
    $: console.log('selectionOption reactivity:', selectedOption);
</script>

<select bind:value={selectedOption}>
    {#each options as opt}
    <option value={opt}>{opt.key}</option>
    {/each}
</select>

https://svelte.dev/repl/bdc48c75acf94a9ca13da377b7cd8f19?version=3.20.1

如果你运行上面的sn -p,每次你尝试从下拉列表中选择(绑定到selectedOption),initialOption的赋值好像又被触发了,为什么?这是预期的行为吗?

【问题讨论】:

    标签: svelte


    【解决方案1】:

    问题有两个方面:

    • 您正在将对象分配给您的反应变量,这些对象在 javascript 中是通过引用而不是通过值分配的
    • 这些变量之一也绑定(以双向绑定)到您的 select 元素的 value 属性

    当您与select 输入进行交互时,您会更新selectedOption 的值,而这又会更新initialOption(因为两个变量都是对同一个对象的引用)。

    你有两种方法可以解决这个问题:

    1. 在选项数组中使用标量而不是对象
    2. 绑定到常规变量而不是响应式变量,而是使用响应式代码来初始化变量

    两种方法都被演示了in this REPL

    【讨论】:

    • 由于selectedOptioninitialOption 是同一个引用,那么当我们更改selectedOption 时,我们会间接触发initialOption 的响应语句?
    • @DanielRS 是的,确切地说,至少这是我的理解,因为当您使用字符串而不是对象时,或者当您继续使用对象但将这两个变量之一设为非时,相同代码的行为方式-反应性。
    猜你喜欢
    • 2021-06-18
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 2012-02-14
    • 2018-07-12
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    相关资源
    最近更新 更多