Skip to content

Reactive statements have incorrect values in functions where dependent values are updated #4586

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

Closed
yuliankarapetkov opened this issue Mar 20, 2020 · 8 comments

Comments

@yuliankarapetkov
Copy link

yuliankarapetkov commented Mar 20, 2020

Describe the bug
Reactive statements have incorrect values in functions where dependent values are updated.

Example:

let count = 0;
$: even = count % 2 === 0

function handleClick() {
  count += 1;
  console.log({ count, even }) // output => { count: 1, even: true }
  // `even` will have incorrect value here, unless `tick()` is being called before it.
}

To Reproduce
REPL

Expected behavior
Reactive statements should have correct (updated) values even if used in a function where their dependent values are updated.

Severity
Critical - I think the current behavior is confusing and might lead to bugs. In fact, I have found this as I was having some weird bugs in production. In addition, using tick() to get the expected behavior in this case is odd and leads to code bloating.

@yuliankarapetkov yuliankarapetkov changed the title Reactive statement has incorrect value in a function where dependent values are updated too Reactive statements have incorrect value in a function where dependent values are updated too Mar 20, 2020
@jdevine
Copy link

jdevine commented Mar 20, 2020

I too have been confused by behavior like this. Perhaps a clearly defined way to isolate atomic units with synchronous reactivity would help those of us still working through the idiosyncrasies of reactivity.

@yuliankarapetkov yuliankarapetkov changed the title Reactive statements have incorrect value in a function where dependent values are updated too Reactive statements have incorrect values in a function where dependent values are updated too Mar 20, 2020
@kevmodrome
Copy link
Contributor

We have discussed this on Discord I believe. Personally I think this is the expected behavior. It follows from how Javascript and the browser works, I think. Having it the other way could lead to strange bugs.

What could be good is a clarifying statement in the documentation.

@yuliankarapetkov yuliankarapetkov changed the title Reactive statements have incorrect values in a function where dependent values are updated too Reactive statements have incorrect values in functions where dependent values are updated Mar 20, 2020
@yuliankarapetkov
Copy link
Author

@kevmodrome Yes, we have discussed it but I still don't think that this should be the behavior.

@Conduitry
Copy link
Member

For performance reasons, $: reactive blocks are batched up and run in the next microtask. This is the expected behavior. This is one of the things that we should talk about when we figure out how and where we want to have a section in the docs that goes into more details about reactivity.

If you want something that updates synchronously and depends on another value, you can use a derived store:

<script>
	import { writable, derived } from 'svelte/store';
	const foo = writable(0);
	const even = derived(foo, $foo => $foo % 2 === 0);
	console.log($foo, $even);
	$foo = 1;
	console.log($foo, $even);
</script>

@yuliankarapetkov
Copy link
Author

@Conduitry Oh, wow, it works like a charm!

Btw, I didn't know that you can directly assign values to stores like this.

$foo = 1;

I thought that you should always use set() or update(). I couldn't find it in the docs, is this official syntax and is it going to work in all cases?

@dimfeld
Copy link
Contributor

dimfeld commented Mar 24, 2020

Easy to miss, but yes it's official syntax and documented at https://svelte.dev/docs#4_Prefix_stores_with_$_to_access_their_values

@stale
Copy link

stale bot commented Dec 24, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale-bot label Dec 24, 2021
@dummdidumm
Copy link
Member

This will be solved in Svelte 5 through the new $derived rune. Whenever you read it, you'll get the current value, no more glitches.

@dummdidumm dummdidumm added this to the 5.x milestone Nov 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants