Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two-way binding breaks in reactive context #3045

Closed
rixo opened this issue Jun 18, 2019 · 3 comments
Closed

Two-way binding breaks in reactive context #3045

rixo opened this issue Jun 18, 2019 · 3 comments
Labels

Comments

@rixo
Copy link
Contributor

rixo commented Jun 18, 2019

Svelte version: 3.5.1

See the following REPL: https://svelte.dev/repl/acdc87a40b914b168c0987572e7876e7?version=3.5.1

When a variable bound with bind: directive has its value set in a reactive context $: ..., the value stops being updated from the component it is bound to.

When the value is assigned again later in the parent component, the two way binding resumes working as expected.

<script>
	import Binder from './Binder.svelte'
	
	let v
	
	$: if  (v > 3) {
		// after this happens, value doesn't get "bound-updated" anymore
		v =  -1 
	}
	
	const onClick = () => {
		// doing this fixes binding state apparently
		v = -2
	}
</script>

<Binder bind:value={v} />

<button on:click={onClick}> Set -2 from parent </button>
@tienpv222
Copy link
Contributor

The tutorial states that using component binding may cause unexpected behavior since there is no "single source of truth". From what I guess, in your case, both parent and children try to modify v at the same time, the compiler can't know which to follow.

A work around would be to call the modifier in the parent after the children.

import { tick } from 'svelte'

$: if (v > 3) {
  tick.then(() => v = -1)
}

or

$: if (v > 3) {
  setTimeout(() => v = -1, 0)
}

@rixo
Copy link
Contributor Author

rixo commented Jun 18, 2019

In my understanding, the tutorial warns against creating binding soup in one's code (like we did in old Angular 1 times). I don't see a warning against a technical limitation in Svelte.

I don't really care about the technical limitation in itself, since there are workarounds, it's a very corner case, etc.

What concerns me is that it's pretty easy to fall into, and that it gives the impression that two-binding in unreliable in Svelte. Unreliable and two-way binding don't go very well together.

So I think the compiler should spit a big warning on this. IMHO it should even crash with an error stating that this situation is not supported.

@Conduitry Conduitry added the bug label Sep 9, 2019
@rixo
Copy link
Contributor Author

rixo commented Nov 12, 2019

This is the same issue as #3382.

Also fixed in 3.14.0: https://svelte.dev/repl/acdc87a40b914b168c0987572e7876e7?version=3.14.0

Closing.

@rixo rixo closed this as completed Nov 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants