Skip to content

Commit 2a7f072

Browse files
Change useStateStore to use useSyncExternalStore instead
1 parent 0577ffd commit 2a7f072

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

src/store/hooks/useStateStore.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import { useEffect, useState } from 'react';
1+
import { useCallback, useMemo, useSyncExternalStore } from 'react';
22

33
import type { StateStore } from 'stream-chat';
44

5+
// eslint-disable-next-line @typescript-eslint/no-empty-function
6+
const noop = () => {};
7+
58
export function useStateStore<
69
T extends Record<string, unknown>,
710
O extends Readonly<Record<string, unknown> | Readonly<unknown[]>>
@@ -14,18 +17,31 @@ export function useStateStore<
1417
T extends Record<string, unknown>,
1518
O extends Readonly<Record<string, unknown> | Readonly<unknown[]>>
1619
>(store: StateStore<T> | undefined, selector: (v: T) => O) {
17-
const [state, setState] = useState<O | undefined>(() => {
18-
if (!store) return undefined;
19-
return selector(store.getLatestValue());
20-
});
20+
const wrappedSubscription = useCallback(
21+
(onStoreChange: () => void) => {
22+
const unsubscribe = store?.subscribeWithSelector(selector, onStoreChange);
23+
return unsubscribe ?? noop;
24+
},
25+
[store, selector],
26+
);
27+
28+
const wrappedSnapshot = useMemo(() => {
29+
let cached: [T, O];
30+
return () => {
31+
const current = store?.getLatestValue();
2132

22-
useEffect(() => {
23-
if (!store) return;
33+
if (!current) return undefined;
2434

25-
const unsubscribe = store.subscribeWithSelector(selector, setState);
35+
if (!cached || cached[0] !== current) {
36+
cached = [current, selector(current)];
37+
return cached[1];
38+
}
2639

27-
return unsubscribe;
40+
return cached[1];
41+
};
2842
}, [store, selector]);
2943

44+
const state = useSyncExternalStore(wrappedSubscription, wrappedSnapshot);
45+
3046
return state;
3147
}

0 commit comments

Comments
 (0)