How does Svelte reactivity work inside functions?
I have some serious problems with reactivity in Svelte. I have isolated what I think is at least one of my main issues. When bind:ing a variable to a checkbox, the reactivity seems to break when setting the variable inside a function, but not outside. Is this intended behavior? In that case why? And what is the intended work flow?
Example code, a Svelte component:
<script>
let foo = true;
// This assignment works both on the plain text view (Foo: true/false)
// and on the checkbox
// setInterval(() => foo = !foo, 500)
// This assignment works only on the plain text view (Foo: true/false)
// but not for the checkbox
function action() {
foo = !foo;
}
</script>
Foo: { foo }<br />
Checkbox: <input type="checkbox" bind:checked={ foo } on:click|preventDefault={ action } />
Svelte REPL to see this problem in action: https://svelte.dev/repl/73de7d705ab3442786710cd88ea3f625?version=3.12.1
Solution 1:
If you wrap your variable declaration in a setTimeout
without any time limit (making it default to 0 and therefore run as soon as possible) your code will work.
function action() {
setTimeout(() => {
foo = !foo;
});
}
I wish I could explain why this works, but I can't...
Solution 2:
The best solution is much simpler, because the two-way binding by itself does everything you need. So, this does it:
<script>
let foo = true;
</script>
Foo: { foo }<br />
Checkbox: <input type="checkbox" bind:checked={ foo } />
I know the question is two years old, but I think it needed better closure.