gpt4 book ai didi

javascript - 当函数中的变量更改时,不会触发 Svelte react 性

转载 作者:行者123 更新时间:2023-12-04 00:15:45 24 4
gpt4 key购买 nike

我在这里有点困惑,不幸的是我无法在 svelte 的不和谐 channel 上找到任何解决方案,所以我开始了......
我有两个类的一个相当基本的例子,让它们成为 AppComp .App创建一个 Comp实例,然后更新此实例的 value单击按钮后。
Comp 实例应将此值设置为不同的变量( inputValue ),并在更改该变量时触发 validate(inputValue)这是 react 性的。这是一个 REPL:https://svelte.dev/repl/1df2eb0e67b240e9b1449e52fb26eb14?version=3.25.1
App.svelte:

<script>
import Comp from './Comp.svelte';

let value = 'now: ' + Date.now();

function clickHandler(e) {
value = 'now ' + Date.now();
}
</script>

<Comp
bind:value={value}
/>
<button type="button" on:click={clickHandler}>change value</button>
比较 slim :
<script>
import { onMount } from 'svelte';

export let value;

let rendered = false;
let inputValue = '';

$: validate(inputValue); // This doesn't execute. Why?

function validate(val) {
console.log('validation:', val);
}

onMount(() => {
rendered = true;
});

$: if (rendered) {
updateInputValue(value);
}

function updateInputValue(val) {
console.log('updateInputValue called!');
if (!value) {
inputValue = '';
}
else {
inputValue = value;
}
}
</script>

<input type="text" bind:value={inputValue}>
因此,一旦更改了值:
  • 无功if (rendered) {...}条件称为
  • updateInputValue被调用并且inputValue被改变。 HTML 输入元素更新为此值。
  • validate(inputValue)从未对这种变化使用react - 为什么?

  • 如果我省略对 updateInputValue 的额外调用 react 中的函数 if (rendered)条件和放置 updateInputValue函数体的代码直接到条件,然后 validate(inputValue)被正确触发,即:
    // works like this  
    $: if (rendered) {
    if (!value) {
    inputValue = '';
    }
    else {
    inputValue = value;
    }
    }
    那么为什么在函数中更新它不起作用呢?

    最佳答案

    @johannchopin 的 answer揭示了这个问题。

    您可以阅读my blogpost for slightly in-depth explanation of how reactive declaration works ,这里是 tl;博士:

  • 响应式声明被执行 批量 .
    svelte 批处理所有更改以在下一个更新周期中更新它们,并且在更新 DOM 之前,它将执行响应式声明以更新响应式变量。
  • 响应式声明被执行 订购 他们的依赖。
    响应式(Reactive)声明是批量执行的,每个声明执行一次。一些声明相互依赖,例如:
    let count = 0;
    $: double = count * 2;
    $: quadruple = double * 2;
    在这种情况下,quadruple取决于 double .所以不管你的 react 声明的顺序如何,$: double = count * 2;之前 $: quadruple = double * 2或者反过来,前者应该是和 将是 在后者之前执行。
    slim 将排序 依赖顺序中的声明。
    在彼此没有依赖关系的情况下:
    $: validate(inputValue);
    $: if (rendered) updateInputValue(value);
    第一条语句取决于 validateinputValue , 第二条语句取决于 rendered , updateInputValuevalue ,声明保持原样。

  • 现在,了解了响应式(Reactive)声明的这两种行为,让我们来看看你的 REPL .
    当你改变 inputValue , renderedvalue , Svelte 将批量更改,并开始新的更新周期。
    在更新 DOM 之前,Svelte 将一次性执行所有的响应式(Reactive)声明。
    因为 validate(inputValue); 之间没有依赖关系和 if (rendered) updateInputValue(value);语句,(如前所述),它们将按顺序执行。
    如果您更改 renderedvalue只有,第一条语句( validate(inputValue) )不会被执行,同样,如果你改变 inputValue第二条语句 ( if (rendered) updateInputValue(value) ) 不会被执行。
    现在,在 updateInputValue您更改 inputValue 的值,但因为我们已经处于更新周期,我们不会开始一个新的。
    这通常不是问题,因为如果我们按照依赖顺序对响应式声明进行排序,更新所依赖变量的语句将在依赖变量的语句之前执行。

    因此,知道出了什么问题,您可以寻求一些“解决方案”。
  • 手动重新排序响应式(Reactive)声明语句,尤其是在执行顺序存在隐式依赖时。

  • 请参阅此 REPL 中订购响应式(Reactive)声明的区别
    因此,将您的 REPL 更改为:
    $: if (rendered) {
    updateInputValue(value);
    }
    $: validate(inputValue);
    See REPL
  • 在响应式声明中显式定义依赖关系

  • $: validate(inputValue);

    $: if (rendered) {
    inputValue = updateInputValue(value);
    }

    function updateInputValue(val) {
    console.log('updateInputValue called!');
    if (!value) {
    return '';
    }
    else {
    return value;
    }
    }
    See REPL

    关于javascript - 当函数中的变量更改时,不会触发 Svelte react 性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63934543/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com