Skip to content

Svelte 5: Higher order dynamic event handlers are not reactive #12520

Closed
@brunnerh

Description

@brunnerh

Describe the bug

Changing an event handler function does not always work as expected when the handler is provided by a higher order function (in terms of the function returning another function).

Noticed this when looking into an issue around dynamic handlers with Svelte 3/4 that does not happen in Svelte 5.

Reproduction

<script>
	let saySomething = $state(name => () => alert('Hello ' + name));

	function change() {
		saySomething = name => () => alert('Bye ' + name);
	}
</script>

<button onclick={saySomething('Tama')}>Tama</button>
<button onclick={saySomething('Pochi')}>Pochi</button>

<br>
<button onclick={change}>Change Function</button>
{saySomething.toString()}

REPL

Dynamic handlers that are not higher order work.
Wrapping the button makes this work (with spread and without).


Longer reproduction to help guard against reintroducing #12519 - the log statements should only happen on handler change:

<script>
	let saySomething = $state(name => {
		console.log('creating "Hello" handler for ' + name);
		return () => alert('Hello ' + name)
	});

	function change() {
		saySomething = name => {
			console.log('creating "Bye" handler for ' + name);
			return () => alert('Bye ' + name);
		}
	}
</script>

<button onclick={saySomething('Tama')}>Tama</button>
<button onclick={saySomething('Pochi')}>Pochi</button>

<br>
<button onclick={change}>Change Function</button>
<pre>{saySomething.toString()}</pre>

REPL

Logs

No response

System Info

REPL

Severity

annoyance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions