UNPKG

1.24 kBJavaScriptView Raw
1import { enqueueRender } from './component';
2
3export let i = 0;
4
5export function createContext(defaultValue) {
6 const ctx = {};
7
8 const context = {
9 _id: '__cC' + i++,
10 _defaultValue: defaultValue,
11 Consumer(props, context) {
12 return props.children(context);
13 },
14 Provider(props) {
15 if (!this.getChildContext) {
16 const subs = [];
17 this.getChildContext = () => {
18 ctx[context._id] = this;
19 return ctx;
20 };
21
22 this.shouldComponentUpdate = _props => {
23 if (this.props.value !== _props.value) {
24 subs.some(c => {
25 c.context = _props.value;
26 enqueueRender(c);
27 });
28 }
29 };
30
31 this.sub = c => {
32 subs.push(c);
33 let old = c.componentWillUnmount;
34 c.componentWillUnmount = () => {
35 subs.splice(subs.indexOf(c), 1);
36 old && old.call(c);
37 };
38 };
39 }
40
41 return props.children;
42 }
43 };
44
45 context.Consumer.contextType = context;
46
47 // Devtools needs access to the context object when it
48 // encounters a Provider. This is necessary to support
49 // setting `displayName` on the context object instead
50 // of on the component itself. See:
51 // https://reactjs.org/docs/context.html#contextdisplayname
52 context.Provider._contextRef = context;
53
54 return context;
55}