-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Fetching an object from a SveltMap, modifying it, then setting it back does not have obvious behavior #14386
Comments
I would say this is expected; possibly a documentation issue if this is not explained. The values are not proxied by default, so changing their properties does nothing. If you make the object a <script>
import { SvelteMap } from 'svelte/reactivity';
let map = $state(new SvelteMap())
setTest('unset');
function setTest(value) {
const test = $state({ value });
map.set('test', test);
}
</script>
<h1>Map Value: {map.get('test').value}</h1>
<button onclick={() => setTest('replaced')}>
Replace value
</button>
<button onclick={() => map.get('test').value = 'modifiedobj'}>
Change value
</button> |
also, |
I actually kind of think something somewhere should warn about this. |
This would be a great thing to document. I thought the documentation where it talks about svelte providing reactive utilities meant that
Maybe this a dumb question. I don't think I understand what a reactive map actually means. So if you do |
Side note:
The difference is that any change to the object via the map's methods trigger reactivity. Usage in the template, an <svelte:options runes />
<script>
import { SvelteMap } from 'svelte/reactivity';
import MapOutput from './MapOutput.svelte';
let map = new Map();
let svelteMap = new SvelteMap();
function addValues() {
map.set(map.size, new Date().toISOString());
svelteMap.set(svelteMap.size, new Date().toISOString());
}
$effect(() => {
// only triggers on mount
console.log('Normal map', [...map]);
});
$effect(() => {
console.log('Svelte map', [...svelteMap]);
});
</script>
<button onclick={addValues}>Add values</button>
<MapOutput map={map}>Normal map</MapOutput>
<MapOutput map={svelteMap}>Svelte map</MapOutput> <!-- MapOutput.svelte -->
<script>
const { map, children } = $props();
</script>
<div>
<strong>{@render children()}</strong> <br>
Size: {map.size} <br>
<pre>{JSON.stringify([...map], null, 2)}</pre>
</div> (Output is split off, otherwise the DOM might still update due to render effect batching, i.e. |
Describe the bug
For
$state([])
you can get an object by index, change it and then set it back and this reactively change. My assumption was that the same behavior would work for a$state(new SvelteMap())
which does not seem to be the case. If you get a value that is an object, modify it and then set it back no reactivity seems to happen. If I set a new object with the same key, things to reactively change. Refer to the playground link for an example.Reproduction
https://svelte.dev/playground/a1144052a70346f9bced094f4d795823?version=5.2.7
Logs
No response
System Info
Severity
annoyance
The text was updated successfully, but these errors were encountered: