svelte icon indicating copy to clipboard operation
svelte copied to clipboard

Bindable, bound & unbound properties

Open cshaa opened this issue 3 years ago • 5 comments

Hey! I'm a long-time React developer who just started learning Svelte, so my view might be a little skewed, but I just wanted to share my thoughts. So far, I love Svelte, but I'm extremely confused by the seeming lack of distinction between ordinary properties and bind:-able properties.

  • Ordinary props serve as an input for a component and change only if the parent changes them. It is my understanding that one should never assign a value to props that aren't supposed to be bind:'ed.

  • Meanwhile, state variables are intended to be internal variables that cannot be read nor set by the parent. They are only changed by the component itself.

  • Bindable props seem like a blend of ordinary props and state variables to me – they are assigned an initial value by the parent, but then they act like an observable state variable.

However, both ordinary props and bindable props are denoted with the same syntax

export let prop;

and Svelte does not differentiate between them. If I wanted, I could add bind: to any prop on a component and Svelte would show no indication that I'm not supposed to, that it will never change. On the other hand, I could take a property that is supposed to be bound and use it as an ordinary property, which would result in no error or warning, but an extremely unintuitive behavior.

Personally, I would very much prefer for ordinary properties to be read-only and for bind: props to have a different syntax – for example:

<script>
  bind: myProp;
  bind: optionalBindProp = 42;
</script>

or using decorators:

<script>
  @bind
  export let myProp;
</script>

Do I just misunderstand the ideas behind bound props? Or would Svelte really benefit from distinguishing the two?

cshaa avatar May 11 '22 10:05 cshaa

Related #5572

dummdidumm avatar May 11 '22 11:05 dummdidumm

Also https://github.com/sveltejs/svelte/issues/2718

Prinzhorn avatar May 12 '22 06:05 Prinzhorn

I also want this.

My understanding is that Svelte uses JavaScript grammar. For example, reactive statements are JS labels, and store binds are valid identifiers. ~~For this reason the bind syntax would not work.~~

Decorators can't be used with variables. I don't know if this is enforced by grammar or something that can be overwritten by Svelte.

Variable decorators are in discussion. https://github.com/wycats/javascript-decorators/issues/32 https://github.com/tc39/proposal-decorators/issues/306

TheCymaera avatar Nov 05 '22 15:11 TheCymaera

reactive statements are JS labels, and store binds are valid identifiers. For this reason the bind syntax would not work.

Why wouldn't it work? This is perfectly valid JS code:

bind: myProp;
bind: optionalBindProp = 42;

REPL

cshaa avatar Nov 22 '22 10:11 cshaa

Sorry, I misread. You're right, that would work.

TheCymaera avatar Nov 22 '22 10:11 TheCymaera

In Svelte 5, props are only bindable if they are marked as such, so I'll close this as completed: https://svelte-5-preview.vercel.app/docs/runes#$bindable

Rich-Harris avatar Apr 02 '24 21:04 Rich-Harris