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

Svelte 5: $effect doesn't run on updates in sveltekit but works properly in svelte 5 REPL #11628

Closed
amit13k opened this issue Jan 13, 2024 · 6 comments

Comments

@amit13k
Copy link

amit13k commented Jan 13, 2024

Describe the bug

effect does not run when the object is modified using bind. This issue doesn't occur in svelte 5 repl and only happens in sveltekit.

Sample code

<script lang="ts">
import NestedComponent from "./nested-component.svelte"
let values = $state({});

$effect(() => {
	// effect only runs once and not on updates in svelte kit
	// this issue doesn't occur in the svelte 5 repl
	console.log('running effect', values);
});

// inspect logs all the updates to the object
$inspect(values);
</script>

<NestedComponent bind:value={values['x']} />

Reproduction

Sveltelab SvelteKit with Svelte 5 with this problem
Svelte 5 REPL without this problem

Logs

No response

System Info

System:
    OS: macOS 14.3
    CPU: (12) arm64 Apple M2 Pro
    Memory: 156.92 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 21.2.0 - /opt/homebrew/bin/node
    Yarn: 1.22.21 - /opt/homebrew/bin/yarn
    npm: 10.2.4 - /opt/homebrew/bin/npm
    pnpm: 8.11.0 - ~/Library/pnpm/pnpm
    bun: 1.0.3 - ~/.bun/bin/bun
  Browsers:
    Chrome: 120.0.6099.216
    Chrome Canary: 122.0.6241.5
    Safari: 17.3

Severity

blocking an upgrade

Additional Information

No response

@brunnerh
Copy link
Member

brunnerh commented Jan 13, 2024

That is expected (if you know why it happens) and unrelated to SvelteKit.

The REPL patches console.log and uses JSON.stringify for the console drawer, this means that every property of the $state is evaluated which each have their own signal. A regular console.log does not do this, so the effect would only run on an assignment to values itself.

If you want the same behavior locally, also use

console.log('running effect', JSON.stringify(values))

@amit13k
Copy link
Author

amit13k commented Jan 13, 2024

That is expected (if you know why it happens) and unrelated to SvelteKit.

The REPL patches console.log and uses JSON.stringify for the console drawer, this means that every property of the $state is evaluated which each have their own signal. A regular console.log does not do this, so the effect would only run on an assignment to values itself.

If you want the same behavior locally, also use

console.log('running effect', JSON.stringify(values))

Thanks for the details regarding this. I understand it now. Does this seem to be a proper way to execute some code whenever something changes in values or is there a better/clean way to do this (when conveniently using bind to modify the object properties)?

$effect(() => {
	JSON.stringify(values);
	
	untrack(() => {
		// execute some code whenever values changes
	});
});

Sveltelab

@brunnerh
Copy link
Member

If you don't need to track deeply nested changes, I would use something like Object.values(values) instead; no need to generate JSON that is not being used.

@amit13k
Copy link
Author

amit13k commented Jan 13, 2024

Thank you. Closing as unrelated to SvelteKit.

@amit13k amit13k closed this as completed Jan 13, 2024
@danawoodman
Copy link
Contributor

danawoodman commented Jan 16, 2025

Is there a related issue for this in Svelte?

This seems to go completely against the documentation which state it should log if the value changes, which it clearly does (bind updates the $state rune's value), confused why this isn't at least considered a bug in Svelte?

Image

EDIT: maybe I misread this; I'm seeing an issue where $inspect does not log values updated by bind, but I guess the OP was having the opposite issue?

@brunnerh
Copy link
Member

I'm seeing an issue where $inspect does not log values updated by bind

If $inspect is not behaving according to the documentation, please open a new issue (in the Svelte repository) and provide the necessary reproduction. $inspect does not evaluate class instances deeply just plain objects/arrays, maybe you ran into that (though manually adding a toJSON() can help here - example).

A related issue:

It looks like there should at least be a caveat in the docs about classes (unless $inspect is changed to account for that).

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

3 participants