-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Description
Describe the bug
We have a class (call it FormManager) in a .svelte.js file. The class has a $derived field which indicates the component for the "current step" of the form.
import Step1 from './Step1.svelte';
import Step2 from './Step2.svelte';
export class FormManager {
steps = $state([
Step1,
Step2
])
currentIndex = $state(0)
CurrentComponent = $derived(this.steps[this.currentIndex])
}
We have another component which renders the current step:
<script>
import { getContext } from 'svelte';
let manager = getContext('formManager');
</script>
<p>Step {manager.currentIndex}</p>
<manager.CurrentComponent />
This component is simple enough to not trigger "runes mode". When the currentIndex changes inside the manager changes, the reactivity isn't completely proper:
- The template render of
{manager.currentIndex}
updates properly - The component does not switch to the updated value of
manager.CurrentComponent
If I do anything that puts the component into runes mode (<svelte:options runes> or just using a rune) then everything works properly. This is easy enough to work around, but also easy to hit accidentally when refactoring code.
In the generated JS I see this, and it isn't placed inside an effect or anything:
$.get(manager).CurrentComponent(node, {});
With runes mode on:
$.component(node, () => manager.CurrentComponent, ($$anchor, manager_CurrentComponent) => {
manager_CurrentComponent($$anchor, {});
});
Reproduction
https://svelte.dev/playground/c49b12d13d2e4e358c995cd37527822a?version=latest
This is a bit different from the description above since it imports the class directly instead of using getContext, but the result is the same.
Logs
System Info
Reproduces in Svelte REPL but I'm using Svelte 5.36.17 and Kit 2.26.1 locally
Severity
annoyance