Replies: 3 comments
-
|
so far i came with this, which does the job but im not sure about possible performance impacts of running this code on every state change reaction(this.state, ['isPlaying', 'progress.position'], ([isPlaying, position]) => {
console.log(isPlaying, position);
});
export const reaction = <S extends object, K extends Paths<S>[]>(
state: S,
keys: [...K],
action: (results: RemapKeysToState<S, [...K]>) => void,
) => {
let changed = false;
const values: Map<string, NestedValueOf<S, Paths<S>>> = new Map();
return subscribe(state, () => {
keys.forEach(key => {
const props = key.split('.');
let value: any = state;
props.forEach(prop => {
value = value[prop];
});
if (values.get(key) !== value) {
changed = true;
values.set(key, value);
}
});
if (changed) {
action(Array.from(values.values()) as RemapKeysToState<S, [...K]>);
changed = false;
}
});
};
type RemapKeysToState<S extends object, T extends Paths<S>[]> = {
[K in keyof T]: NestedValueOf<S, T[K]>;
};
type Paths<T> = T extends Array<infer U>
? `${Paths<U>}`
: T extends object
? {
[K in keyof T & (string | number)]: K extends string ? `${K}` | `${K}.${Paths<T[K]>}` : never;
}[keyof T & (string | number)]
: never;
type NestedValueOf<Obj, Key extends string> = Obj extends object
? Key extends `${infer Parent}.${infer Leaf}`
? Parent extends keyof Obj
? NestedValueOf<Obj[Parent], Leaf>
: never
: Key extends keyof Obj
? Obj[Key]
: never
: never; |
Beta Was this translation helpful? Give feedback.
0 replies
-
|
Valtio isn't designed to be a mobx replacement from the beginning, and "reaction" is one of such features that are excluded by design. |
Beta Was this translation helpful? Give feedback.
0 replies
-
import { proxy, snapshot, subscribe as _subscribe } from "valtio/vanilla";
// ...
export interface State {
// ...
}
export const state = proxy<State>({
// ...
});
export const subscribe = <T>(
selector: (state: State) => T,
cb: (v: T) => void
): ReturnType<typeof _subscribe> => {
let oldValue = selector(snapshot(state) as State);
return _subscribe(state, () => {
const newValue = selector(snapshot(state) as State);
if (oldValue === newValue) return;
oldValue = newValue;
cb(selector(state));
});
};this should do the trick |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
seems like a core piece of functionality is missing – i need to track a primitive change in vanilla inside a deeply nested proxified state, but it seems to be impossible with valtio.
subscribeKeyonly works on root level properties of a proxy,subscribedoesn't work on primitives, and so doeswatch. Any idea how mobx does it with theirreaction/autorun? It would be extremely useful.Beta Was this translation helpful? Give feedback.
All reactions