-
Notifications
You must be signed in to change notification settings - Fork 0
/
createFastContext.js
63 lines (51 loc) · 1.28 KB
/
createFastContext.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import React, {
useRef,
createContext,
useContext,
useCallback,
useSyncExternalStore,
} from "react";
export default function createFastContext(initialState) {
function useStoreData() {
const store = useRef(initialState);
const get = useCallback(() => store.current, []);
const subscribers = useRef(new Set());
const set = useCallback((value) => {
store.current = { ...store.current, ...value };
subscribers.current.forEach((callback) => callback());
}, []);
const subscribe = useCallback((callback) => {
subscribers.current.add(callback);
return () => subscribers.current.delete(callback);
}, []);
return {
get,
set,
subscribe,
};
}
const StoreContext = createContext(null);
function Provider({ children }) {
return (
<StoreContext.Provider value={useStoreData()}>
{children}
</StoreContext.Provider>
);
}
function useStore(selector) {
const store = useContext(StoreContext);
if (!store) {
throw new Error("Store not found");
}
const state = useSyncExternalStore(
store.subscribe,
() => selector(store.get()),
() => selector(initialState),
);
return [state, store.set];
}
return {
Provider,
useStore,
};
}