Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$: reactive statement ignored during beforeUpdate #8750

Closed
ibmua opened this issue Jun 17, 2023 · 6 comments
Closed

$: reactive statement ignored during beforeUpdate #8750

ibmua opened this issue Jun 17, 2023 · 6 comments
Milestone

Comments

@ibmua
Copy link

ibmua commented Jun 17, 2023

Describe the bug

$: reactive statements are ignored if values are modified in beforeUpdate.

Reproduction

Solve https://learn.svelte.dev/tutorial/update
and add

	$: {
		console.log("autoscroll", autoscroll)
	}

You'll see that nothing will be logged. If you add some variable changes like


let st = true
	$: {
		console.log("autoscroll", autoscroll)
		st = !st
	}

you'll see they don't change

Logs

No response

System Info

https://learn.svelte.dev/tutorial/update on Chrome

Severity

Pretty serious bug

@stordahl
Copy link
Contributor

stordahl commented Jul 2, 2023

@ibmua I've been able to recreate what you've described in learn.svelte.dev, but after creating this repro repl, I don't think this is a Svelte issue. Could be something about the web containers setup (I'm not really sure). Let me know if the repro accurately reproduces the scenario you've outlined

@MrAmericanMike
Copy link

MrAmericanMike commented Oct 26, 2023

I'm not sure I fully understand what the issue here is, but I'm intrigued by this part of the code.

$: {
	console.log({val1, val2, domDep}),
	val2 = !val2
}

If we are updating the value of val2 inside this reactive block, and the block is supposed to run each time val2 changes because we are logging it to the console. Wouldn't this cause (shouldn't this cause) an infinite loop?

@7nik
Copy link

7nik commented Oct 27, 2023

No, it doesn't. When a variable changes (marked dirty), the following happens:

  1. looping over each $: block and running the ones that depend on dirtied variables;
  2. running beforeUpdate;
  3. marking all variables as up to date;
  4. updating DOM;
  5. running afterUpdate.

Step 3 prevents infinite loops, plus proper udirting variables individually is too tricky or probably even impossible.

@dummdidumm
Copy link
Member

Svelte 5 will change the behavior here using the new Runes API. Using $effect and $effect.pre you can listen to the variables you're interested in and it will always refire when they changed.
Note that the REPL in the second post would result in an infinite loop right now because it's writing and reading the same value, triggering the effect over and over again. We may look into fixing more obvious cases of this / warn against it so that doesn't happen as easily.

@dummdidumm dummdidumm added this to the 5.x milestone Nov 15, 2023
@7nik
Copy link

7nik commented Nov 15, 2023

I thought about infinite loops cause by self-triggering $effect and came to idea that if your logic cause infinite loops then the logic is wrong and it needs some loop guard or its improvement.

But maybe it would nice to be able to disable $effects' self-triggering though a flag in the second param. Though it may not solve infinite loops over multiple $effects.

@benmccann benmccann modified the milestones: 5.x, 5.0 Nov 17, 2023
@dummdidumm
Copy link
Member

Closing since this will be addressed in Svelte 5 as pointed out in #8750 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants