Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

326
Visualizações
svelte: how can I declare two cyclically reactive variables?

I have two variables a and b which add up to 100. How do I set up a reactive declaration such that when a changes b changes to be 100 - a and vice versa? When I try something like

let total = 100;
$: a = total - b;
$: b = total - a;

I get a 'Cyclical dependency detected' error. Is there any way to get this done?

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

The problem comes from the fact that Svelte wants to sort the reactive blocks in the order they depend upon each other: it wants to compute those that are depended upon but have no dependencies first, to avoid unneeded computation... or getting trapped in a loop.

Furthermore, Svelte considers a dependency of a reactive expression any reactive variable that appear in it.

And so, the actual source of your error is that both variables a and b appears in both reactive expressions.

The solution is to remove from the reactive expressions the unneeded variable, that is the one that is assigned to. This can be done by moving the assignment to a function outside of the reactive block. Unfortunately, it's more verbose...

<script>
    let total = 100;
    let a = 0
    let b = 0
    
    const setA = () => {
        // the assignment to a (or b in the other function) are still
        // reactive, of course, but Svelte won't propagate changes to
        // variable that are assigned their current value, so this
        // will break the loop
        a = total - b
    }
    
    const setB = () => {
        b = total - a
    }
    
    $: setA(total - b);
    $: setB(total - a);
</script>

<pre>
    a: {a}
    b: {b}
</pre>

<label>
    a <input type="number" bind:value={a} />
</label>

<label>
    b <input type="number" bind:value={b} />
</label>
about 4 years ago · Juan Pablo Isaza Relatório

0

That does not work; Svelte does not allow this and this cycle cannot be resolved either. If you want a variable to be editable, you cannot declare it as reactive ($: x = ...). You can either reactively set regular variables with reactive statements/blocks or use events instead (see other answers).

The following is an explanation why this could not be resolved logically either.

Treating this like two equations with two unknowns you get this useless simplification:

a = total - b
b = total - a
b = total - (total - b)
b = total - total + b
b = b

You have to fix at least one of the values, otherwise all possible values are valid here.


You can also first normalize the equations:

a = total - b => a + b = total => a + b = total
b = total - a => b + a = total => a + b = total

As you can see, they are the same, so you actually have two unknowns and only one equation, so this is underspecified.

(Note that even if this would yield a valid solution, Svelte cannot solve systems of linear equations for you.)

about 4 years ago · Juan Pablo Isaza Relatório

0

Unless you need the values to update from programmatic changes, i would drop the reactive statements entirely and work with events instead: When one variable is adjusted by the user, update the other one.

<script>
  const total = 100;
  let a = total;
  let b = 0;
</script>

a: {a} <br>
b: {b}

<label>
  a <input type="number" bind:value={a}
           on:input={() => b = total - a} />
</label>

<label>
  b <input type="number" bind:value={b}
           on:input={() => a = total - b} />
</label>
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda