Description
Describe the bug
A common scenario is list/item components:
- A List component has a selectedValue
- An Item component has a value and shows as selected when the value and selectedValue are equal
- Item components are added as children to the List
- To avoid a caller from having to pass the selectedValue to every Item, the List puts the selectedValue on the context
In Svelte 5 as of 2024-09-10, when the Item directly uses the selectedValue from context to determine selected state, every item in the list renders whenever selectedValue changes. This happens if the comparison happens directly in the HTML binding (expected), or if $derived is used (unexpected).
The workaround is to use $effect and track selected as $state, only updating it if the selectedValue === value changes.
It seems like $derived is firing a state change causing a render whenever selectedValue changes even if the result doesn't change (i.e. selected was false and is set to false). Shouldn't $derived not raise a state change if the value doesn't change?
Reproduction
Here is repro in the svelte preview REPL.
Look at the output each time the selection changes and you will see 3 console entries from $inspected.
Here is the same, but with the workaround enabled.
Now the output from $inspect shows only the previous and new selected items rendering.
Logs
No response
System Info
This is in the Svelte REPL.
Severity
annoyance