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