Describe the bug
I have two components :
Cpn.svelte
<script>
export let items = [];
</script>
and a consumer :
<script>
import Cpn from './Cpn';
let items = []
</script>
<Cpn {items} bind:items/>
this consumer has a "bug" : it injects {items} and creates a binding with items. However svelte doesn't output any warning, and the generated code has an infinite loop when the component is rendered.
It "worked" in svelte 3.12
The bug is not really in svelte but in my code, however it's a "hard to debug" case, because chrome/firefox just crash every time the component is shown (and it worked in 3.12).
To Reproduce
I can't provide a REPL because this bug crashes the app.
Expected behavior
The generated code doesn't have an infinite loop/svelte emits an error.
Information about your Svelte project:
Svelte detects when you add the same attribute twice:
<Component value="1" value="2" />
Will correctly give you the error: Attributes need to be unique
However
<Component value="1" bind:value />
Does not give the same error, although I think it should considering it's somehow also a duplicate attribute.
Yeah, I agree that foo={...}, {foo}, and bind:foo should probably all be mutually exclusive, and using any two of them should be a compile-time error.
In 3.18.2, it's now a compiler error to have any two of foo=..., {foo}, or bind:foo.
I think that this should be allowed though.
<input type="text" value={value} bind:value={query} />
I don't know what value={value} bind:value={query} would be used for, or how a component with those on an element would behave.
I used this construct in an autocomplete dropdown component, where I wanted to keep the query and the selected value separated.
We use this to set an initial value on an input, but at the same time keep it up to date. How would we change that to work with these changes?
You would set the bound-to value to an initial value.
let items = ["item1"];
<Cpn bind:items />
So bind goes both ways? The documentation would make it seem that it just does one-way, from parent to child. Thank you for pointing that out!
Data ordinarily flows down, from parent to child. The bind: directive allows data to flow the other way, from child to parent.
The docs are maybe a bit ambiguous, it could indeed be interpreted as _bind_ reversing the flow, while in reality it allows data to flow both ways.
Most helpful comment
Yeah, I agree that
foo={...},{foo}, andbind:fooshould probably all be mutually exclusive, and using any two of them should be a compile-time error.