Last active
September 17, 2023 13:15
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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