WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Function bindings are not deeply reactive #17383

@AgarwalPragy

Description

@AgarwalPragy

Describe the bug

When using function bindings, the binding setter is invoked only when the bound property is "replaced".
If the bound property is a $state and is updated internally, the binding setter is not invoked.

This can lead to subtle bugs since the state & UI reacts correctly thanks to the deep reactivity of $state - just that the binding's setter is not invoked

Reproduction

https://svelte.dev/playground/eb92a6bcf6a84b99a31d9e5e15fc6815?version=5.46.0

App.svelte

<svelte:options runes />
<script lang="ts">
	import Component from './Component.svelte'
	
	let visibility = $state({red: true, blue: true})
</script>

<pre>{JSON.stringify(visibility, null, 2)}</pre>

<Component bind:visibility={
	() => visibility,
	(v) => {
		console.log('setter called')
		visibility = v
	}
} />

Component.svelte

<script lang="ts">
	let {visibility = $bindable()} = $props()

	function toggleDeep() {
		// the following updates the state without invoking the binding setter
		visibility.blue = !visibility.blue
	}

	function toggleShallow() {
		// the following updates the state and correctly invokes the binding setter
		visibility = {...visibility, blue: !visibility.blue}
	}
</script>
<button onclick={toggleDeep}>Toggle Deep</button>
<button onclick={toggleShallow}>Toggle Shallow</button>

Logs

System Info

svelte: 5.46.0
runes enabled

Severity

annoyance

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions