-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcreate-context.js
More file actions
65 lines (55 loc) · 1.52 KB
/
Copy pathcreate-context.js
File metadata and controls
65 lines (55 loc) · 1.52 KB
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
64
65
import { enqueueRender } from './component';
export let i = 0;
export function createContext(defaultValue, contextId) {
contextId = '__cC' + i++;
const context = {
_id: contextId,
_defaultValue: defaultValue,
/** @type {FunctionComponent} */
Consumer(props, contextValue) {
// return props.children(
// context[contextId] ? context[contextId].props.value : defaultValue
// );
return props.children(contextValue);
},
/** @type {FunctionComponent} */
Provider(props) {
if (!this.getChildContext) {
/** @type {Component[] | null} */
let subs = [];
let ctx = {};
ctx[contextId] = this;
this.getChildContext = () => ctx;
this.componentWillUnmount = () => {
subs = null;
};
this.shouldComponentUpdate = function (_props) {
if (this.props.value !== _props.value) {
subs.some(c => {
c._force = true;
enqueueRender(c);
});
}
};
this.sub = c => {
subs.push(c);
let old = c.componentWillUnmount;
c.componentWillUnmount = () => {
if (subs) {
subs.splice(subs.indexOf(c), 1);
}
if (old) old.call(c);
};
};
}
return props.children;
}
};
// Devtools needs access to the context object when it
// encounters a Provider. This is necessary to support
// setting `displayName` on the context object instead
// of on the component itself. See:
// https://reactjs.org/docs/context.html#contextdisplayname
return (context.Provider._contextRef = context.Consumer.contextType =
context);
}