-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuse-context-selector.js
39 lines (31 loc) · 1.02 KB
/
use-context-selector.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
import { createContext as createContextOrig, useLayoutEffect, useRef, useReducer } from "react";
const createProvider = (ProviderOrig) => {
const ContextProvider = ({ value, children }) => {
const contextValue = useRef();
if (!contextValue.current) {
const listeners = new Set();
contextValue.current = {
value,
listeners,
}
}
useLayoutEffect(() => {
contextValue.current.value = value;
contextValue.current.listeners.forEach((listener) => {
listener({ v: value })
})
}, [value])
return <ProviderOrig value={contextValue.current}>{children}</ProviderOrig>;
}
return ContextProvider
}
function createContext(defaultValue) {
const context = createContextOrig({ value: defaultValue, listeners: new Set() })
context.Provider = createContext(context.Provider)
delete context.Consumer;
return context
}
function useContextSelector(context, selector) {
const contextValue = useContextOrig(context);
const { value, listeners } = contextValue;
}