sveltejs / svelte

Cybernetically enhanced web apps
https://svelte.dev
MIT License
78.04k stars 4.08k forks source link

Svelte 5 reactivity breaks using objects, when parent is not using runes mode #12032

Closed oaksmedia closed 2 months ago

oaksmedia commented 2 months ago

Describe the bug

Svelte 5 reactivity breaks using objects, when parent is not using runes mode.

Is it possible to save svelte5 Repls? I can't

Reproduction

App.svelte


<script>
    import Component from './Component.svelte'
    import ComponentNested from './ComponentNested.svelte'

</script>
<Component />

Component.svelte

<svelte:options runes={false}/>
<script>
        import ComponentNested from './ComponentNested.svelte'
        let firstState = {name:'test'}
</script>
{firstState.name}
<ComponentNested {firstState}/>

ComponentNested.svelte

<script>
        let {firstState = $bindable({})} = $props()
</script>
{firstState['name']}
<input type="text" bind:value={firstState['name']} />

You will find that firstName['name'] does not change value.

Logs

No response

System Info

Svelte5-next, and on the Repl

Severity

annoyance

dummdidumm commented 2 months ago

The problem is that Svelte 5 puts out $$props.firstState['name'] = newValue for the binding, which is fine when both components are in runes mode, but not fine when the parent is not in runes mode.

Possible solution:

harrisi commented 2 months ago

REPL. The URL of the svelte 5 preview REPL stores the state, so to share you just copy the URL.

trueadm commented 2 months ago

The problem is that Svelte 5 puts out $$props.firstState['name'] = newValue for the binding, which is fine when both components are in runes mode, but not fine when the parent is not in runes mode.

Possible solution:

  • these kinds of things need to use the same method as in legacy mode
  • that method has knowledge whether or not the parent is in runes mode and if yes is a noop

I'm not sure if the first point is possible, nor the second point. If you use a component in multiple places, one where its parent is runes and one where it is not, it will have unexpected outcomes.

I'm half wondering if we should allow parent components to be legacy components. A whole wrath of issues could be closed in a single swipe if we only allowed sub-trees to be legacy.