Skip to content

Instantly share code, notes, and snippets.

@paulcalcraft
Last active September 17, 2023 13:15
Show Gist options
  • Save paulcalcraft/5e9ea299cf2e37d0105295889e1a9eb8 to your computer and use it in GitHub Desktop.
Save paulcalcraft/5e9ea299cf2e37d0105295889e1a9eb8 to your computer and use it in GitHub Desktop.
Svelte bug report: Array assignment reactivity not working; adding a line-end comment bizarrely fixes it
<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)}
<p><tt>propdata</tt> is incorrectly invalidated on line 13 when editedData is invalidated, breaking the Add button.</p>
<p>Bizarrely, this is fixed if you add any line-end comment to line 13, e.g. <tt>editedData = editedData // this works</tt></p>
<p>If you add a semicolon AND a comment, it does not work, so the following is still broken: <tt>editedData = editedData; // this doesn't work</tt></p>
<p>The JS output for add() without the comment is:</p>
<pre>{`
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));
}`}
</pre>
<p>We see that <tt>propdata</tt> is incorrectly invalidated alongside <tt>editedData</tt>.</p>
<p>The JS output for add() <strong>with</strong> the comment (working correctly) is:</p>
<pre>{`
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); //
}`}
</pre>
<p>Only <tt>editedData</tt> is invalidated.</p>
<!--
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 ]
-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment