svelte icon indicating copy to clipboard operation
svelte copied to clipboard

Svelte 5: element ref bindings require $state and shouldn't

Open j opened this issue 1 year ago • 4 comments
trafficstars

Describe the bug

HTML element refs shouldn't need to be reactive.

In the repro, if I use onMount, I don't get the warning. In a realistic use-case, this element can be used in $effect, etc.

<script>
	import { onMount } from 'svelte';
	
	let ref; // ref is updated, but is not declared with $state(...). Changing its value will not correctly trigger updates.

	$effect(() => {
		console.log(ref)
	})
</script>

<div bind:this={ref} />

Related to #9684

Reproduction

https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAE0WNQQrCMBBFrzIMQlsouq9twQN4AutC24kG0pmQTAUJubtEFy7-4n3e5yc01lHE7pKQbythhyfvsUV9-wLxRU4JW4yyhbk0fZyD9TpOPKldvQSFBMJn2VghgwmyQvWbVccilThSCGQK86Q7MoZmresGhhHSV9JZOIqjvZNHHcg0pc3NxP3hf8j9Yl9wt7x0-rRxSIFMhsOILa6yWGNpwU7DRvmaP8GdEDfaAAAA

Logs

ref is updated, but is not declared with $state(...). Changing its value will not correctly trigger updates.

System Info

System:
    OS: macOS 14.2.1
    CPU: (10) arm64 Apple M2 Pro
    Memory: 92.78 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.9.0 - ~/Library/Caches/fnm_multishells/8438_1707428836388/bin/node
    Yarn: 1.22.21 - ~/Library/Caches/fnm_multishells/8438_1707428836388/bin/yarn
    npm: 10.1.0 - ~/Library/Caches/fnm_multishells/8438_1707428836388/bin/npm
    pnpm: 8.12.1 - /opt/homebrew/bin/pnpm
    bun: 1.0.25 - ~/.bun/bin/bun
  Browsers:
    Safari: 17.2.1
  npmPackages:
    svelte: ^5.0.0-next.1 => 5.0.0-next.51

Severity

annoyance

j avatar Feb 08 '24 21:02 j

It could be necessary to have a $state, e.g. if the bound element does not always exist because it is wrapped in an {#if} block.

brunnerh avatar Feb 09 '24 00:02 brunnerh

Sure, yeah I stated they don't need to be reactive and in most cases aren't.

j avatar Feb 09 '24 00:02 j

This is tricky for sure. In the above case we can determine that it doesn't need to be reactive. Logic could be something like "is this ever reassigned or is inside a block which could make it update", and "is this read in a reactive context".

In general, it's probably ok to have a few more false negatives here.

dummdidumm avatar Feb 09 '24 12:02 dummdidumm

@dummdidumm exactly what I was thinking. determining if something MIGHT need to truly be interactive via re-assignment, etc would be ideal

j avatar Feb 09 '24 20:02 j