Skip to content

Svelte 5: Unpredictable behavior of $effect statements #13813

@vhtmui

Description

@vhtmui

Describe the bug

The $effect rune behaves differently when variables are declared in different places.

Consider this code:

<script>
	let {display = true} = $props();//case 1
	// let display = $state(true); //case 2

	let Istrue = true;

  function toggle_display() {
		display = !display
	}

// this run everytime click the button if  `display` is in the $props statement.
	$effect(()=>{
		if (Istrue){
			display = true;
			alert("alert from $effect!");
		}
	})
</script>

<button onclick={toggle_display} >display</button>

{#if display && true}
	<h1>Hello world</h1>
{/if}

In case 1, display declaration is in the $props statement, this will cause the $effect statement runs everytime i click the button.
In case 2, display declaration as a reactive varriable, the $effect statement will not runs one time.

From my perspective, $effect should only run when the value of the if statement changes, which is counterintuitive right now. I'm not sure if it's a feature or a bug, but I hope $effect's behavior to be consistent in this two case. Because this work well in svelte 4 with afterUpdate, it seems that $effect cannot replace afterUpdate.

Reproduction

https://svelte.dev/playground/8507880e5cb74c13a4d6dd67e645092a?version=5.0.5

Logs

No response

System Info

nothing

Severity

annoyance

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions