main
js 83 lines 2.36 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 */
9
10 import {disableLegacyContext} from 'shared/ReactFeatureFlags';
11 import getComponentNameFromType from 'shared/getComponentNameFromType';
12
13 let warnedAboutMissingGetChildContext;
14
15 if (__DEV__) {
16 warnedAboutMissingGetChildContext = {} as {[string]: boolean};
17 }
18
19 export const emptyContextObject: {} = {};
20 if (__DEV__) {
21 Object.freeze(emptyContextObject);
22 }
23
24 export function getMaskedContext(type: any, unmaskedContext: Object): Object {
25 if (disableLegacyContext) {
26 return emptyContextObject;
27 } else {
28 const contextTypes = type.contextTypes;
29 if (!contextTypes) {
30 return emptyContextObject;
31 }
32
33 const context: {[string]: $FlowFixMe} = {};
34 for (const key in contextTypes) {
35 context[key] = unmaskedContext[key];
36 }
37
38 return context;
39 }
40 }
41
42 export function processChildContext(
43 instance: any,
44 type: any,
45 parentContext: Object,
46 childContextTypes: Object,
47 ): Object {
48 if (disableLegacyContext) {
49 return parentContext;
50 } else {
51 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
52 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
53 if (typeof instance.getChildContext !== 'function') {
54 if (__DEV__) {
55 const componentName = getComponentNameFromType(type) || 'Unknown';
56
57 if (!warnedAboutMissingGetChildContext[componentName]) {
58 warnedAboutMissingGetChildContext[componentName] = true;
59 console.error(
60 '%s.childContextTypes is specified but there is no getChildContext() method ' +
61 'on the instance. You can either define getChildContext() on %s or remove ' +
62 'childContextTypes from it.',
63 componentName,
64 componentName,
65 );
66 }
67 }
68 return parentContext;
69 }
70
71 const childContext = instance.getChildContext();
72 for (const contextKey in childContext) {
73 if (!(contextKey in childContextTypes)) {
74 throw new Error(
75 `${
76 getComponentNameFromType(type) || 'Unknown'
77 }.getChildContext(): key "${contextKey}" is not defined in childContextTypes.`,
78 );
79 }
80 }
81 return {...parentContext, ...childContext};
82 }
83 }