Open NullVoxPopuli opened 2 months ago
It would be nice to have a utility similar to MobX's reaction()
function.
reaction()
is very useful when you need to track the pervious value of a signal. You give it a tracked data function and an untracked effect function that's run when the value changes.
Something a bit like this:
export const reaction = <T>(
data: () => T,
effect: (value: T, previousValue: T) => void,
equality = Object.is,
) => {
const computed = new Signal.Computed(data);
let previousValue = computed.get();
let isReacting = false;
const watcher = new Signal.subtle.Watcher(async () => {
if (isReacting === true) {
return;
}
isReacting = true;
await 0;
isReacting = false;
const value = computed.get();
if (!equality(previousValue, value)) {
effect(value, previousValue);
previousValue = value;
}
});
watcher.watch(computed);
};
oo nice! that does seem useful -- I know quite a few folks that would like such a utility for caching or memoizing complex calculations (tho I don't know an exact use case, but I know it's desired!).
Would you be willing to submit a PR adding this utility along with a bunch of tests? (so we can ensure behavior is retained as the polyfill (and spec) evolves?)
Reminds me of Vue's watch
function that allows to declare multiple signals ("refs") to track:
https://vuejs.org/api/reactivity-core.html#watch
@signal
(wrapper aroundnew Signal.State
)@localCopy
@keepLatest
@dedupe
@cached
(computed, but on a getter)localStorage
/@localStorage
Blocked on framework-specific semantics and timing (cleanup)