UNPKG

2.05 kBJavaScriptView Raw
1import { enqueueRender } from './component';
2
3export let i = 0;
4
5export function createContext(defaultValue, contextId) {
6 contextId = '__cC' + i++;
7
8 const context = {
9 _id: contextId,
10 _defaultValue: defaultValue,
11 Consumer(props, contextValue) {
12 // return props.children(
13 // context[contextId] ? context[contextId].props.value : defaultValue
14 // );
15 return props.children(contextValue);
16 },
17 Provider(props, subs, ctx) {
18 if (!this.getChildContext) {
19 subs = [];
20 ctx = {};
21 ctx[contextId] = this;
22
23 this.getChildContext = () => ctx;
24
25 this.shouldComponentUpdate = function(_props) {
26 if (this.props.value !== _props.value) {
27 // I think the forced value propagation here was only needed when `options.debounceRendering` was being bypassed:
28 // https://github.com/preactjs/preact/commit/4d339fb803bea09e9f198abf38ca1bf8ea4b7771#diff-54682ce380935a717e41b8bfc54737f6R358
29 // In those cases though, even with the value corrected, we're double-rendering all nodes.
30 // It might be better to just tell folks not to use force-sync mode.
31 // Currently, using `useContext()` in a class component will overwrite its `this.context` value.
32 // subs.some(c => {
33 // c.context = _props.value;
34 // enqueueRender(c);
35 // });
36
37 // subs.some(c => {
38 // c.context[contextId] = _props.value;
39 // enqueueRender(c);
40 // });
41 subs.some(enqueueRender);
42 }
43 };
44
45 this.sub = c => {
46 subs.push(c);
47 let old = c.componentWillUnmount;
48 c.componentWillUnmount = () => {
49 subs.splice(subs.indexOf(c), 1);
50 if (old) old.call(c);
51 };
52 };
53 }
54
55 return props.children;
56 }
57 };
58
59 // Devtools needs access to the context object when it
60 // encounters a Provider. This is necessary to support
61 // setting `displayName` on the context object instead
62 // of on the component itself. See:
63 // https://reactjs.org/docs/context.html#contextdisplayname
64
65 return (context.Provider._contextRef = context.Consumer.contextType = context);
66}