-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Svelte 5: disallow fallback values for bindings #9764
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
Comments
It seems that the "proposed solution" REPL is instead the "proposed code causing error REPL" about the error
I also made a simpler one However, on latest Win11 VScode, I only get the error too late, in the console when running the vite dev server, and not with the usual |
Also @Rich-Harris, can you provide links for the discussions about
please ? I imagine the confusion could come from their misleading behavior compared to other framework (see #9764 (comment)) I personally think that instead of getting rid of fallbacks values entirely, we should apply the proposed solution in #9948. It would both more intuitive (same functioning that other framework) and easier than having the boilerplate $effect(() => {
if (propName === undefined) {
propName = propNameDefaultValue
}
}) for each prop (which also have the big downside that |
Huh, I'm actually quite confused by this as well. The docs for Svelte 4 say that At the same time, the workaround is just setting the default immediately after the Note that in There's some additional weirdness here, where the child component has to set the default values if it wants to ensure correct operation, or manually check the types, as far as I can tell: REPL. Maybe that's just a REPL issue or a bug, though. I'm not convinced of anything right now because I'm not quite sure I understand why this change was made. |
It is wired, child component can change the value but can not have default value. It will force us to add some boilerplate for some use-cases. 👎 |
Here is one more problem: I suggest to add a smarter ability to set default values.
Because, Svelte is a compiler - it should add above code automatically, if we write this: |
Or alternatively, to set when let { propName } = $props();
propName ??= propNameDefaultValue |
Interesting, but this is a non-reactive class-constructor-like default value edit: code updated: |
I believe it works the same way as solidjs; you need to use an effect to respond to future prop changes. Without effect: With effect: |
in Solid, you use: in Vue, you use: in React, you use: |
Solid and React don't have a concept for two way bindings, so the comparison is flawed |
But Vue does have it, so the comparison is valid |
Can’t we just ignore the default value when a prop is bound, but allow it otherwise? You might not know in advance whether a particular prop will be bound when writing a component. I’d say, it isn’t even component’s responsibility to know whether somebody bounds it’s props. |
As the time pass, I'm more and more against the idea to disallow fallback values for binding. |
Can this be escalated? |
We merged a relaxation of the fallback values: The runtime error is only thrown if you bind |
This sounds reasonable. Is it available in the repl already? |
Although I'd expect that it would bound literally "undefined" to the property (ignoring fallback completely) |
@dummdidumm I think that the #9948 proposal is more desirable, and would theoretically be incompatible with that relaxation. As I stated in that issue, the "initial" value behavior outlined in its description is perhaps the direct cause of confusion about props (what has caused Rich to disallow fallback values for binding in the first place). |
These two are not directly related - but judging from your response, you would want |
That's true indeed,
Exactly Moreover, that's the standard most of the big names in frontend framework has adopted, such as React, Vue, and Solid (see #9948 (comment)) |
Update#10797 has been merged |
I have a simple case that’s unsupported, but I see a straightforward if verbose workaround. I want to be able to define a fallback in a child’s bindable prop, and then use the child without providing an initial value. This would allow parents to receive the fallback in the binding after the child initializes without being forced to override it.
Shortened from the REPL, demonstrating the limitation described in the quote above: <script>
// Parent.svelte
// This throws the error:
// props_invalid_value - Cannot do `bind:value={undefined}` when `value` has a fallback value
let value = $state(); // same as `$state(undefined)`
</script>
<Child bind:value />
<script>
// Child.svelte
let {value = $bindable('initial')} = $props();
</script> Allowing the parent to pass undefined to a bindable with a fallback would make the fallbacks of In other words, children can't provide bindable initial defaults to their parents without a workaround. This case makes them not the "real" default values described in #9948. The workaround I can see: // Child.svelte
let {value = $bindable()} = $props();
if (value === undefined) value = 'initial'; // needed so `value` is correct during the child's initialization
$effect.pre(() => {
if (value === undefined) value = 'initial';
}); But it would be nice to write: // Child.svelte
let {value = $bindable('initial')} = $props(); Behaving the same as this, but bindable, so parents can pass // Child.svelte
let {value = 'initial'} = $props(); A different partial workaround would be to export the fallback value from the child's module context and use it in the parents' initial values, but that value couldn't use the child's local state and it duplicates the declarations. I have several of these cases in my projects. One concrete example is a hue input - the input component needs to choose an arbitrary starting point like 180 degrees, and I want parents to be able to use this default for consistency across the app without needing to define their own initial values, and update: After rewriting some code because of this limitation, I think I'm glad I was nudged away from |
Describe the problem
More of an anti-feature request: we resolved to disallow fallback values for bindings in runes mode. They're confusing, and a source of bugginess and implementation complexity
Describe the proposed solution
https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAE42PwWrDMBBEf2URhTg02M1VtQ0hn9H0EMtrqkaWhLQuFKF_ryyFNKU9lD2NtDP7JrBJKvSMvwSmzzMyzg7Wsh2jT7sK_4GKMGlvFifWl9YLJy31Jw0gZ2scwfFNqhEmZ2bY1E1WdTFunk86DSkkMMM7CoIOHjydCasAwiyaODxB3Ka9trklJ1EyB6lHfjU26aO1fSiyzubYNrZPdLMZ5SRxZJzcgnF3K5Nj_lenUIZvznvANAncOmN99Rt2WIiMBqOFkuLShWoLXQ9hzbynhccO9skcYz6Xlz2Hn43W7JL3R7HX-AWtI2YRsQEAAA==
Alternatives considered
n/a
Importance
nice to have
The text was updated successfully, but these errors were encountered: