-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Description
Describe the problem
I use $derived
or $derived.by
to "couple" state widely in my app. For example like so:
const baseObj = $state(...)
const derivedObj = $derived.by(() => {
// Not possible here, because it cannot reference itself
// derivedObj.destroy()
const _obj = new DerivedObj(baseObj)
_obj.setup()
return _obj
})
The baseObj
might not be a primitive type, but rather a class with "complex behaviour", for example in many cases a rxjs.Observable
inside. When I create a new DerivedObj(baseObj)
from that baseObj
, then I might want to setup listeners/subscriptions on baseObj
, which should be unsubscribed/destroyed on the old derivedObj
, when it is recreated by $derived
.
This raises the need for a destructor function.
Describe the proposed solution
$effect
currently has something like "destuctor support": (see Preview Docs)
You can return a function from $effect, which will run immediately before the effect re-runs, and before it is destroyed (demo)."
Therefore it might make sense to implement it similarly for $derived
.
There should be a functionality that does this (sentence from $effect
docs reformulated):
You can specify a "destuctor" function, which will run immediately before the
derived.by
re-runs, and before it is destroyed.
I could imagine using it like so:
const baseObj = $state(...)
const derivedObj = $derived.by(
// "constructor"
() => {
const _obj = new DerivedObj(call, modalVC)
_obj.setup()
return _obj
},
// "destructor"
() => {
derivedObj.destroy()
}
)
The destructor should be run immediately before $derived
reruns and creates a new object from the source state. And before $derived
is destroyed, so that the destructor is also called when a component is destroyed, otherwise we have to repeat the destructor inside onDestroy(() => derivedObj.destroy())
, which would be repeating every time.
Importance
i cannot use svelte without it