Description
Describe the bug
I've been using this pattern from a @PatrickG's comment and I consider it a decent userland-implementation for $state.link
:
let count = $state(0);
const linked = $derived.by(()=>{
const state = $state({ current: count });
return state;
})
linked.current++;
It worked fine in earlier versions of Svelte 5. However, after the performance patch in PR #14533, object ownership isn't added for $state
inside $derived
anymore. Quote:
Potentially someone could create a $state while creating $state.raw or inside a $derived.by, but that feels so much of an edge case that it doesn't warrant a perf hit for the common case.
As a consequence, trying to use this pattern across component boundaries, either via the context API or props will produce the ownership_invalid_binding
warning, even with proper prop binding. I've seen people asking problems that can be solved perfectly by this pattern, but I'm hesitant to recommend it to them. Sometimes I offer an alternative solution using $effect
instead and they're happy to use it because there's no warning. However I feel bad about using $effect
because 1. it's not synchronous and 2. updating states inside it is considered a bad practice.
Recently I saw a @paoloricciuti 's comment regarding this pattern and it may be even added to the docs. I'm relieved that it's a valid pattern that is recognized by the team. I feel like it's time the revisit the ownership check for this case again, especially after the recent PR #15153.
Reproduction
https://svelte.dev/playground/d51b66bbb70e413498fe70b23944fcd7?version=5.19.6
Logs
System Info
N/A
Severity
annoyance