svelte icon indicating copy to clipboard operation
svelte copied to clipboard

Svelte 5: <svelte:component bind:this={ref} /> ref is undefined

Open johannesmutter opened this issue 2 years ago • 3 comments

Describe the bug

In Svelte 5 <svelte:component this={component} bind:this={component_ref} /> will return "undefined" for component_ref.

This is annoying in cases where you want to e.g. dynamically trigger events like component_ref.click() from outside. A workaround is to use classic document.querySelector.

Reproduction

REPL: https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAE42SvU7DMBSFX-XKQmorVQ0Dk5tYAl4AiZEglMY3xWpiW7YDtFFWNiQWBqZOvBhP0EdAzg8pPypsuUffOTm2b0UykaMl9KoiMimQUHKqNZkSt9Z-sHeYOyRTYlVpUq-ENjVCOxbL2IlCK-PgQq3wTN3nkBlVwGgW9MKstY_m-7DYbJKB9NMXLEcHqSq0kigdRHBkXeJw3EdOfkI3BrMB9EAYDCVluCidUxKUTHORrqJqPIlYtf-LpkRdM4tdvTBoPexf7q5ZH9CNexmxDNsT0sHnboWNhpwaFkJy-k31J6shaCM0u8QcU4ccznuAQmh1Itk3Sxg0KozfH5-hlBwzIZFPWBjoro5b59g8oQeh8l-xWyTpamlUKTkFg3zeqjrhXMglhWM40Q-NWDdX3GSQKSkUF5lATqgzJdbTz03qr-LgOmnmMfDcbvv26isezPTv81dgs2K77dPL72nX9QfkPCtV9wIAAA==

Logs

No response

System Info

Svelte v5.0.0-next.40

Severity

annoyance

johannesmutter avatar Jan 26 '24 15:01 johannesmutter

bind:this on a component will "return" a component instance but not a DOM element!

ref is undefined because your components have no properties on instance - you can define them with export const x = 42; and export function name() {} - than you'll get an object with these methods/props.

7nik avatar Jan 26 '24 16:01 7nik

Shouldn't it still give you the component instance? It looks like if you export something you get a Proxy but if not you get undefined. In Svelte 4 I'm using get_current_component() in a WeakMap in some edge cases and wonder if you won't be able to get a consistent reference to a component instance (what you would get via new Comp()) in Svelte 5?

Prinzhorn avatar Jan 26 '24 17:01 Prinzhorn

Component API is changed in Svelte 5. You can read a bit in #9827. Also, there is no get_current_component() anymore (see #9189), and I don't see an alternative. It was a private API, and using it always was a bad idea.

It's arguable whether an instance of a component without accessors should be undefined or {}. It's more convenient always to receive an object, but on the other hand, creating empty accessor objects, which is the case for most components, wastes CPU and RAM and slightly worsens performance.

7nik avatar Jan 26 '24 17:01 7nik

The component now always returns at least {} so it's going to be defined, therefore closing.

dummdidumm avatar Mar 07 '24 10:03 dummdidumm