svelte icon indicating copy to clipboard operation
svelte copied to clipboard

Svelte 5: Nonstate reference warning is too aggressive

Open Rich-Harris opened this issue 2 years ago • 3 comments

Describe the bug

#9669 introduced a warning for mutated nonstate that is referenced in the template. It shouldn't apply in cases like this, because the compiler should assume that obj.count could be an accessor:

<script>
	let count = $state(0);

	let obj = {
		get count() {
			return count;
		},
		set count(v) {
			count = v;
		}
	}

	function increment() {
		obj.count += 1;
	}
</script>

<button on:click={increment}>
	clicks: {obj.count}
</button>

In other words it should only apply to identifiers that aren't part of a MemberExpression, and only when the value is reassigned rather than simply mutated.

Reproduction

https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAE01QSw7CIBC9CiEuNBo_W9qaeA7rosWpQduhgaGJIdxdWmx1NXlv3ofB80a1YLm4eo5VB1zwS9_zHad3PwI7QEsQsdXOyJHJrTSqp3OJJbVATGqHxAq2slQRrI-bLG6-O10_48aPsKTHLF5vZqokA-QMJj5LZNilaRf98GeY64ZZPY6QKhuHkpRGplAa6OC_Kj5ln7zbgp2yrys__K7BvHZE0a1RyFbJV-GXnDCdO7FWML-ETRHJdo6f1Om7ahTcuSDjINzCB3wP_0BfAQAA

Logs

No response

System Info

next

Severity

annoyance

Rich-Harris avatar Nov 28 '23 12:11 Rich-Harris

I'm also getting this warning on a TypeScript enum:

<script lang="ts">
  enum Which {
    First,
    Second,
  }
  let which = $state(Which.First);
</script>

<button onclick={(): void => {
        which = Which.Second;
    }}>
    {which}
</button>
warning  Which is updated, but is not declared with $state(...). Changing its value will not correctly trigger updates.(non-state-reference)  svelte/valid-compile

I'm only getting it from eslint and not Svelte itself though.

sockmaster27 avatar Nov 28 '23 13:11 sockmaster27

I'm seeing the same warning with the below simplified example. It's used to wrap an external library as a component.

<script>
let ref;
let grid;
grid = new Grid(ref);
</script>

<div bind:this={ref} />

The warning is both in the compiler and Svelte extension for VSC. ref is updated, but is not declared with $state(...). Changing its value will not correctly trigger updates.

System info [email protected]

thorsby avatar Jan 02 '24 15:01 thorsby

Way to aggressive. Dom refs don't need to be reactive. Even the listed examples in Svelte 5 docs disagree with compiler and eslint warnings.

https://component-party.dev/?f=svelte4,svelte5#dom-ref

gregmulvaney avatar Jan 11 '24 22:01 gregmulvaney

This has been fixed.

trueadm avatar Feb 23 '24 12:02 trueadm

Still seeing this for enum which is declared in <script lang="ts" context="module"> block

eunukasiko avatar Mar 08 '24 08:03 eunukasiko

It has not been fixed for DOM elements being binded @trueadm

quinnvaughn avatar Aug 01 '24 17:08 quinnvaughn

Can you provide a repro in the playground?

Rich-Harris avatar Aug 02 '24 19:08 Rich-Harris

Experiencing this issue as well, the repro looks like this, though I don't think the playground shows those kinds of link warnings (or does it?): https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAE0VPTWvDMAz9K0Ls0LJAumuaFHbYP9itGTRxlEbMkUMsrwzj_z6cQHfU-9J7EUe25LG6RpRuJqzwfVmwQP1d8uF_yCphgd6F1WSk9mblRS-ttGpJwbggCg28eO2UDqfjuZXMjUGMshNgMSvNJHo4QsxMq7vntYG3LNa0O3Jar_Jhz1CW8DmxB8tCcCf1oBPBo1uF5Q5DIFC3QbeeZah0Yn-Dnqx7tFKX_w2l7oOqE3BiLJvvJj7bJHham7i9TdumTecriFvJlPP2jAsWOLuBR6YBK10Dpa_0B4kJDiNAAQAA

Anyway, this is what it looks like on my editor image

cmendoza-cs avatar Aug 09 '24 02:08 cmendoza-cs

Experiencing this issue as well, the repro looks like this, though I don't think the playground shows those kinds of link warnings (or does it?): https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAE0VPTWvDMAz9K0Ls0LJAumuaFHbYP9itGTRxlEbMkUMsrwzj_z6cQHfU-9J7EUe25LG6RpRuJqzwfVmwQP1d8uF_yCphgd6F1WSk9mblRS-ttGpJwbggCg28eO2UDqfjuZXMjUGMshNgMSvNJHo4QsxMq7vntYG3LNa0O3Jar_Jhz1CW8DmxB8tCcCf1oBPBo1uF5Q5DIFC3QbeeZah0Yn-Dnqx7tFKX_w2l7oOqE3BiLJvvJj7bJHham7i9TdumTecriFvJlPP2jAsWOLuBR6YBK10Dpa_0B4kJDiNAAQAA

Anyway, this is what it looks like on my editor image

It should...can you check which version of svelte you are using locally?

paoloricciuti avatar Aug 09 '24 06:08 paoloricciuti

It should...can you check which version of svelte you are using locally?

I currently have 5.0.0-next.210

cmendoza-cs avatar Aug 09 '24 07:08 cmendoza-cs

Experiencing this issue as well, the repro looks like this, though I don't think the playground shows those kinds of link warnings (or does it?): https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAE0VPTWvDMAz9K0Ls0LJAumuaFHbYP9itGTRxlEbMkUMsrwzj_z6cQHfU-9J7EUe25LG6RpRuJqzwfVmwQP1d8uF_yCphgd6F1WSk9mblRS-ttGpJwbggCg28eO2UDqfjuZXMjUGMshNgMSvNJHo4QsxMq7vntYG3LNa0O3Jar_Jhz1CW8DmxB8tCcCf1oBPBo1uF5Q5DIFC3QbeeZah0Yn-Dnqx7tFKX_w2l7oOqE3BiLJvvJj7bJHham7i9TdumTecriFvJlPP2jAsWOLuBR6YBK10Dpa_0B4kJDiNAAQAA

Anyway, this is what it looks like on my editor image

The REPL can be oversimplified. Where and how do you use btnEl?

7nik avatar Aug 09 '24 07:08 7nik

Oh i just realized: it will only trigger if you have the bound element in an if or each or key basically some block that could make the element change

example

paoloricciuti avatar Aug 09 '24 07:08 paoloricciuti

Oh i just realized: it will only trigger if you have the bound element in an if or each or key basically some block that could make the element change

Oh wow, I was just trying to figure out why some of my bound variables don't exhibit that issue. I just tested and yeah that does seem to explain it.

cmendoza-cs avatar Aug 09 '24 07:08 cmendoza-cs

I'll close this as I think we've covered the various cases — we can reopen with examples if not

Rich-Harris avatar Aug 12 '24 21:08 Rich-Harris