-
Hi want to know whether anyone tried using rxjs with zustand |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 7 replies
-
I didn't try. But, and anyone can correct me if I'm wrong, I don't think you can use rxjs with zustand because the implementation of the |
Beta Was this translation helpful? Give feedback.
-
Here's a small example someone made: https://codesandbox.io/s/x2icz |
Beta Was this translation helpful? Give feedback.
-
Here's an attempt to implement a toStream function similar to mobx-utils that can take a store, selector and output a RxJS observable. I'm not sure how to "correctly" infer the State shape given only the StoreApi interface, especially since various middleware like Note: Only very roughly tested with Please feel free to modify/use without attribution in any way you like. // zustand-utils.ts
import type { Observable } from 'rxjs';
import { fromEventPattern } from 'rxjs';
import type { EqualityChecker, GetState, StateSelector } from 'zustand/vanilla';
type InferState<
TStore extends {
getState: GetState<object>;
}
> = TStore extends {
getState: GetState<infer TState>;
}
? TState
: never;
/**
* Create a zustand selector as an RxJS observable, inspired
* by the MobX toStream API: https://github.com/mobxjs/mobx-utils#tostream
*/
export const toStream = <
TStore extends {
getState: GetState<object>;
},
TStateSlice,
TState extends object = InferState<TStore>
>(
store: TStore,
selector: StateSelector<TState, TStateSlice>,
options?: {
equalityFn?: EqualityChecker<TStateSlice>;
fireImmediately?: boolean;
}
): Observable<TStateSlice> => {
const result = fromEventPattern<TStateSlice>(
(handler) =>
(store as any).subscribe(
selector,
(value) => {
handler(value);
},
options
),
(_handler, signal) => signal()
);
return result;
}; Usageimport { combine, subscribeWithSelector } from 'zustand/middleware';
import create from 'zustand/vanilla';
import { toStream } from './zustand-utils';
const store = create(
subscribeWithSelector(
combine({ bears: 0 }, (set) => ({
increase: (by: number) => set((state) => ({ bears: state.bears + by })),
}))
)
);
// type is Observable<number>
const bears$ = toStream(store, (state) => state.bears, {
fireImmediately: true,
}); |
Beta Was this translation helpful? Give feedback.
Here's an attempt to implement a toStream function similar to mobx-utils that can take a store, selector and output a RxJS observable.
I'm not sure how to "correctly" infer the State shape given only the StoreApi interface, especially since various middleware like
subscribeWithSelector
override thesubscribe()
function and the subscribe function itself seems to have multiple signatures too. My attempt is shown attype InferState
, but maybe the preferred way to do this in Zustand is to provide a middleware that exposes a new function on the StoreApi?Note: Only very roughly tested with
zustand/vanilla
.Please feel free to modify/use without attribution in any way you like.
// zustand-utils.ts