Skip to content

Array assignment reactivity not working; adding a line-end comment bizarrely fixes it #9221

Closed
@paulcalcraft

Description

@paulcalcraft

Describe the bug

In this short example, propdata is incorrectly invalidated when triggering reactivity on editedData with editedData = editedData, which keeps resetting the array to its default value whenever you try to add to it. This problem strangely goes away if you add a comment to the end of the reactivity line. (Change line 13 to editedData = editedData // this works.)

<script>
    // copy this script to https://svelte.dev/repl/
    // (github login on svelte.dev is not working for me, so I cannot save on the REPL)
    export let propdata = [1, 1]
    console.log("initial propdata", propdata)
    $: editedData = [...propdata]
    
    function add() {
        console.log("clicked")
        editedData.push(1)
	console.log("element added, editedData set to (no reactivity)", editedData)
        console.log("triggering reactivity on editedData", editedData)
        editedData = editedData
    }
    $: console.log("$: propdata set to", propdata)
    $: console.log("$: editedData set to", editedData)
</script>
<button on:click={add}>Add</button>
{JSON.stringify(editedData)}

The JS output for add() without the comment is:

function add() {
	console.log("clicked");
	editedData.push(1);
	console.log("element added, editedData set to (no reactivity)", editedData);
	console.log("triggering reactivity on editedData", editedData);
	($$invalidate(0, editedData), $$invalidate(2, propdata));
}

We see that propdata is incorrectly invalidated alongside editedData.

The JS output for add() with the comment (working correctly) is:

function add() {
	console.log("clicked");
	editedData.push(1);
	console.log("element added, editedData set to (no reactivity)", editedData);
	console.log("triggering reactivity on editedData", editedData);
	$$invalidate(0, editedData = editedData); // this works
}

Only editedData is invalidated.

The problem doesn't occur if you use editedData = [...editedData, 1], but my understanding is that reactivity should also work with push and reassign.

Reproduction

Code for repro is here, just copy to svelte.dev REPL:
https://gist.github.com/paulcalcraft/5e9ea299cf2e37d0105295889e1a9eb8

Unfortunately I'm not able to login via github to svelte.dev REPL so I can't save the REPL, hence the gist. But that's another bug report for another time.

Logs

Console output after clicking Add twice, showing Add button does not update editedData:

"initial propdata" (2) [ 1 ,1 ]
"$: propdata set to" (2) [ 1 ,1 ]
"$: editedData set to" (2) [ 1 ,1 ]
"clicked"
"element added, editedData set to (no reactivity)" (3) [ 1 ,1 ,1 ]
"triggering reactivity on editedData" (3) [ 1 ,1 ,1 ]
"$: propdata set to" (2) [ 1 ,1 ]
"$: editedData set to" (2) [ 1 ,1 ]
"clicked"
"element added, editedData set to (no reactivity)" (3) [ 1 ,1 ,1 ]
"triggering reactivity on editedData" (3) [ 1 ,1 ,1 ]
"$: propdata set to" (2) [ 1 ,1 ]
"$: editedData set to" (2) [ 1 ,1 ]

System Info

System:
    OS: Windows 10 10.0.22621
    CPU: (8) x64 Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
    Memory: 3.76 GB / 15.81 GB
  Binaries:
    Node: 18.16.1 - C:\Program Files\nodejs\node.EXE
    npm: 9.7.2 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 116.0.5845.188
    Edge: Spartan (44.22621.2283.0), Chromium (116.0.1938.81)
    Internet Explorer: 11.0.22621.1
  npmPackages:
    svelte: ^4.0.5 => 4.2.0 

The problem is also currently reproducing on the live svelte.dev REPL.

Severity

annoyance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions