@samitouri / QOS-React / commits / f9358c51c8

Change warning() to automatically inject the stack, and add warningWithoutStack() as opt-out (#13161)

* Use %s in the console calls * Add shared/warningWithStack * Convert some warning callsites to warningWithStack * Use warningInStack in shared utilities and remove unnecessary checks * Replace more warning() calls with warningWithStack() * Fixes after rebase + use warningWithStack in react * Make warning have stack by default; warningWithoutStack opts out * Forbid builds that may not use internals * Revert newly added stacks I changed my mind and want to keep this PR without functional changes. So we won't "fix" any warnings that are already missing stacks. We'll do it in follow-ups instead. * Fix silly find/replace mistake * Reorder imports * Add protection against warning argument count mismatches * Address review

Dan Abramov committed Jul 16, 2018 at 22:31 UTC f9358c51c8de93abe3cdd0f4720b489befad8c48
59 files changed +426 -390
packages/create-subscription/src/createSubscription.js
+3 -3
@@ -9,7 +9,7 @@
9
10 import React from 'react';
11 import invariant from 'shared/invariant';
12 -import warning from 'shared/warning';
12 +import warningWithoutStack from 'shared/warningWithoutStack';
13
14 type Unsubscribe = () => void;
15
@@ -36,11 +36,11 @@ export function createSubscription<Property, Value>(
36 }> {
37 const {getCurrentValue, subscribe} = config;
38
39 - warning(
39 + warningWithoutStack(
40 typeof getCurrentValue === 'function',
41 'Subscription must specify a getCurrentValue function',
42 );
43 - warning(
43 + warningWithoutStack(
44 typeof subscribe === 'function',
45 'Subscription must specify a subscribe function',
46 );
packages/events/EventPluginUtils.js
+3 -3
@@ -7,7 +7,7 @@
7
8 import ReactErrorUtils from 'shared/ReactErrorUtils';
9 import invariant from 'shared/invariant';
10 -import warning from 'shared/warning';
10 +import warningWithoutStack from 'shared/warningWithoutStack';
11
12 export let getFiberCurrentPropsFromNode = null;
13 export let getInstanceFromNode = null;
@@ -21,7 +21,7 @@ export const injection = {
21 getNodeFromInstance,
22 } = Injected);
23 if (__DEV__) {
24 - warning(
24 + warningWithoutStack(
25 getNodeFromInstance && getInstanceFromNode,
26 'EventPluginUtils.injection.injectComponentTree(...): Injected ' +
27 'module is missing getNodeFromInstance or getInstanceFromNode.',
@@ -46,7 +46,7 @@ if (__DEV__) {
46 ? dispatchInstances.length
47 : dispatchInstances ? 1 : 0;
48
49 - warning(
49 + warningWithoutStack(
50 instancesIsArr === listenersIsArr && instancesLen === listenersLen,
51 'EventPluginUtils: Invalid `event`.',
52 );
packages/events/EventPropagators.js
+2 -2
@@ -10,7 +10,7 @@ import {
10 traverseTwoPhase,
11 traverseEnterLeave,
12 } from 'shared/ReactTreeTraversal';
13 -import warning from 'shared/warning';
13 +import warningWithoutStack from 'shared/warningWithoutStack';
14
15 import {getListener} from './EventPluginHub';
16 import accumulateInto from './accumulateInto';
@@ -46,7 +46,7 @@ function listenerAtPhase(inst, event, propagationPhase: PropagationPhases) {
46 */
47 function accumulateDirectionalDispatches(inst, phase, event) {
48 if (__DEV__) {
49 - warning(inst, 'Dispatching inst must not be null');
49 + warningWithoutStack(inst, 'Dispatching inst must not be null');
50 }
51 const listener = listenerAtPhase(inst, event, phase);
52 if (listener) {
packages/events/ResponderTouchHistoryStore.js
+3 -3
@@ -8,7 +8,7 @@
8 */
9
10 import invariant from 'shared/invariant';
11 -import warning from 'shared/warning';
11 +import warningWithoutStack from 'shared/warningWithoutStack';
12
13 import {isStartish, isMoveish, isEndish} from './ResponderTopLevelEventTypes';
14
@@ -95,7 +95,7 @@ function resetTouchRecord(touchRecord: TouchRecord, touch: Touch): void {
95 function getTouchIdentifier({identifier}: Touch): number {
96 invariant(identifier != null, 'Touch object is missing identifier.');
97 if (__DEV__) {
98 - warning(
98 + warningWithoutStack(
99 identifier <= MAX_TOUCH_BANK,
100 'Touch identifier %s is greater than maximum supported %s which causes ' +
101 'performance issues backfilling array locations for all of the indices.',
@@ -200,7 +200,7 @@ const ResponderTouchHistoryStore = {
200 }
201 if (__DEV__) {
202 const activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch];
203 - warning(
203 + warningWithoutStack(
204 activeRecord != null && activeRecord.touchActive,
205 'Cannot find single active touch.',
206 );
packages/events/SyntheticEvent.js
+3 -3
@@ -8,7 +8,7 @@
8 /* eslint valid-typeof: 0 */
9
10 import invariant from 'shared/invariant';
11 -import warning from 'shared/warning';
11 +import warningWithoutStack from 'shared/warningWithoutStack';
12
13 let didWarnForAddedNewProperty = false;
14 const EVENT_POOL_SIZE = 10;
@@ -261,7 +261,7 @@ if (__DEV__) {
261 !target.constructor.Interface.hasOwnProperty(prop) &&
262 shouldBeReleasedProperties.indexOf(prop) === -1
263 ) {
264 - warning(
264 + warningWithoutStack(
265 didWarnForAddedNewProperty || target.isPersistent(),
266 "This synthetic event is reused for performance reasons. If you're " +
267 "seeing this, you're adding a new property in the synthetic event object. " +
@@ -316,7 +316,7 @@ function getPooledWarningPropertyDefinition(propName, getVal) {
316
317 function warn(action, result) {
318 const warningCondition = false;
319 - warning(
319 + warningWithoutStack(
320 warningCondition,
321 "This synthetic event is reused for performance reasons. If you're seeing this, " +
322 "you're %s `%s` on a released/nullified synthetic event. %s. " +
packages/react-dom/src/client/ReactDOM.js
+10 -10
@@ -33,7 +33,7 @@ import ReactSharedInternals from 'shared/ReactSharedInternals';
33 import getComponentName from 'shared/getComponentName';
34 import invariant from 'shared/invariant';
35 import lowPriorityWarning from 'shared/lowPriorityWarning';
36 -import warning from 'shared/warning';
36 +import warningWithoutStack from 'shared/warningWithoutStack';
37
38 import * as ReactDOMComponentTree from './ReactDOMComponentTree';
39 import * as ReactDOMFiberComponent from './ReactDOMFiberComponent';
@@ -64,7 +64,7 @@ if (__DEV__) {
64 typeof Set.prototype.clear !== 'function' ||
65 typeof Set.prototype.forEach !== 'function'
66 ) {
67 - warning(
67 + warningWithoutStack(
68 false,
69 'React depends on Map and Set built-in types. Make sure that you load a ' +
70 'polyfill in older browsers. https://fb.me/react-polyfills',
@@ -77,7 +77,7 @@ if (__DEV__) {
77 container._reactRootContainer._internalRoot.current,
78 );
79 if (hostInstance) {
80 - warning(
80 + warningWithoutStack(
81 hostInstance.parentNode === container,
82 'render(...): It looks like the React-rendered content of this ' +
83 'container was removed without using React. This is not ' +
@@ -93,7 +93,7 @@ if (__DEV__) {
93 rootEl && ReactDOMComponentTree.getInstanceFromNode(rootEl)
94 );
95
96 - warning(
96 + warningWithoutStack(
97 !hasNonRootReactChild || isRootRenderedBySomeReact,
98 'render(...): Replacing React-rendered children with a new root ' +
99 'component. If you intended to update the children of this node, ' +
@@ -101,7 +101,7 @@ if (__DEV__) {
101 'and render the new components instead of calling ReactDOM.render.',
102 );
103
104 - warning(
104 + warningWithoutStack(
105 container.nodeType !== ELEMENT_NODE ||
106 !((container: any): Element).tagName ||
107 ((container: any): Element).tagName.toUpperCase() !== 'BODY',
@@ -114,7 +114,7 @@ if (__DEV__) {
114 };
115
116 warnOnInvalidCallback = function(callback: mixed, callerName: string) {
117 - warning(
117 + warningWithoutStack(
118 callback === null || typeof callback === 'function',
119 '%s(...): Expected the last optional `callback` argument to be a ' +
120 'function. Instead received: %s.',
@@ -472,7 +472,7 @@ function legacyCreateRootFromDOMContainer(
472 (rootSibling: any).hasAttribute(ROOT_ATTRIBUTE_NAME)
473 ) {
474 warned = true;
475 - warning(
475 + warningWithoutStack(
476 false,
477 'render(): Target node has markup rendered by React, but there ' +
478 'are unrelated nodes as well. This is most commonly caused by ' +
@@ -590,7 +590,7 @@ const ReactDOM: Object = {
590 if (owner !== null && owner.stateNode !== null) {
591 const warnedAboutRefsInRender =
592 owner.stateNode._warnedAboutRefsInRender;
593 - warning(
593 + warningWithoutStack(
594 warnedAboutRefsInRender,
595 '%s is accessing findDOMNode inside its render(). ' +
596 'render() should be a pure function of props and state. It should ' +
@@ -667,7 +667,7 @@ const ReactDOM: Object = {
667 const rootEl = getReactRootElementInContainer(container);
668 const renderedByDifferentReact =
669 rootEl && !ReactDOMComponentTree.getInstanceFromNode(rootEl);
670 - warning(
670 + warningWithoutStack(
671 !renderedByDifferentReact,
672 "unmountComponentAtNode(): The node you're attempting to unmount " +
673 'was rendered by another copy of React.',
@@ -696,7 +696,7 @@ const ReactDOM: Object = {
696 isValidContainer(container.parentNode) &&
697 !!container.parentNode._reactRootContainer;
698
699 - warning(
699 + warningWithoutStack(
700 !hasNonRootReactChild,
701 "unmountComponentAtNode(): The node you're attempting to unmount " +
702 'was rendered by React and is not a top-level container. %s',
packages/react-dom/src/client/ReactDOMFiberComponent.js
+20 -36
@@ -8,12 +8,10 @@
8 */
9
10 // TODO: direct imports like some-package/src/* are bad. Fix me.
11 -import {
12 - getCurrentFiberOwnerNameInDevOrNull,
13 - getCurrentFiberStackInDev,
14 -} from 'react-reconciler/src/ReactCurrentFiber';
11 +import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber';
12 import {registrationNameModules} from 'events/EventPluginRegistry';
13 import warning from 'shared/warning';
14 +import warningWithoutStack from 'shared/warningWithoutStack';
15
16 import * as DOMPropertyOperations from './DOMPropertyOperations';
17 import * as ReactDOMFiberInput from './ReactDOMFiberInput';
@@ -61,8 +59,6 @@ const HTML = '__html';
59
60 const {html: HTML_NAMESPACE} = Namespaces;
61
64 -let getStackInDev = () => '';
65 -
62 let warnedUnknownTags;
63 let suppressHydrationWarning;
64
@@ -76,8 +72,6 @@ let normalizeMarkupForTextOrAttribute;
72 let normalizeHTML;
73
74 if (__DEV__) {
79 - getStackInDev = getCurrentFiberStackInDev;
80 -
75 warnedUnknownTags = {
76 // Chrome is the only major browser not shipping <time>. But as of July
77 // 2017 it intends to ship it due to widespread usage. We intentionally
@@ -123,7 +117,7 @@ if (__DEV__) {
117 return;
118 }
119 didWarnInvalidHydration = true;
126 - warning(
120 + warningWithoutStack(
121 false,
122 'Text content did not match. Server: "%s" Client: "%s"',
123 normalizedServerText,
@@ -149,7 +143,7 @@ if (__DEV__) {
143 return;
144 }
145 didWarnInvalidHydration = true;
152 - warning(
146 + warningWithoutStack(
147 false,
148 'Prop `%s` did not match. Server: %s Client: %s',
149 propName,
@@ -167,7 +161,7 @@ if (__DEV__) {
161 attributeNames.forEach(function(name) {
162 names.push(name);
163 });
170 - warning(false, 'Extra attributes from the server: %s', names);
164 + warningWithoutStack(false, 'Extra attributes from the server: %s', names);
165 };
166
167 warnForInvalidEventListener = function(registrationName, listener) {
@@ -176,19 +170,17 @@ if (__DEV__) {
170 false,
171 'Expected `%s` listener to be a function, instead got `false`.\n\n' +
172 'If you used to conditionally omit it with %s={condition && value}, ' +
179 - 'pass %s={condition ? value : undefined} instead.%s',
173 + 'pass %s={condition ? value : undefined} instead.',
174 registrationName,
175 registrationName,
176 registrationName,
183 - getCurrentFiberStackInDev(),
177 );
178 } else {
179 warning(
180 false,
188 - 'Expected `%s` listener to be a function, instead got a value of `%s` type.%s',
181 + 'Expected `%s` listener to be a function, instead got a value of `%s` type.',
182 registrationName,
183 typeof listener,
191 - getCurrentFiberStackInDev(),
184 );
185 }
186 };
@@ -266,11 +258,7 @@ function setInitialDOMProperties(
258 }
259 }
260 // Relies on `updateStylesByID` not mutating `styleUpdates`.
269 - CSSPropertyOperations.setValueForStyles(
270 - domElement,
271 - nextProp,
272 - getStackInDev,
273 - );
261 + CSSPropertyOperations.setValueForStyles(domElement, nextProp);
262 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
263 const nextHtml = nextProp ? nextProp[HTML] : undefined;
264 if (nextHtml != null) {
@@ -326,11 +314,7 @@ function updateDOMProperties(
314 const propKey = updatePayload[i];
315 const propValue = updatePayload[i + 1];
316 if (propKey === STYLE) {
329 - CSSPropertyOperations.setValueForStyles(
330 - domElement,
331 - propValue,
332 - getStackInDev,
333 - );
317 + CSSPropertyOperations.setValueForStyles(domElement, propValue);
318 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
319 setInnerHTML(domElement, propValue);
320 } else if (propKey === CHILDREN) {
@@ -369,7 +353,7 @@ export function createElement(
353 isCustomComponentTag = isCustomComponent(type, props);
354 // Should this check be gated by parent namespace? Not sure we want to
355 // allow <SVG> or <mATH>.
372 - warning(
356 + warningWithoutStack(
357 isCustomComponentTag || type === type.toLowerCase(),
358 '<%s /> is using incorrect casing. ' +
359 'Use PascalCase for React components, ' +
@@ -408,7 +392,7 @@ export function createElement(
392 !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)
393 ) {
394 warnedUnknownTags[type] = true;
411 - warning(
395 + warningWithoutStack(
396 false,
397 'The tag <%s> is unrecognized in this browser. ' +
398 'If you meant to render a React component, start its name with ' +
@@ -445,7 +429,7 @@ export function setInitialProperties(
429 !didWarnShadyDOM &&
430 (domElement: any).shadyRoot
431 ) {
448 - warning(
432 + warningWithoutStack(
433 false,
434 '%s is using shady DOM. Using shady DOM with React can ' +
435 'cause things to break subtly.',
@@ -523,7 +507,7 @@ export function setInitialProperties(
507 props = rawProps;
508 }
509
526 - assertValidProps(tag, props, getStackInDev);
510 + assertValidProps(tag, props);
511
512 setInitialDOMProperties(
513 tag,
@@ -611,7 +595,7 @@ export function diffProperties(
595 break;
596 }
597
614 - assertValidProps(tag, nextProps, getStackInDev);
598 + assertValidProps(tag, nextProps);
599
600 let propKey;
601 let styleName;
@@ -837,7 +821,7 @@ export function diffHydratedProperties(
821 !didWarnShadyDOM &&
822 (domElement: any).shadyRoot
823 ) {
840 - warning(
824 + warningWithoutStack(
825 false,
826 '%s is using shady DOM. Using shady DOM with React can ' +
827 'cause things to break subtly.',
@@ -902,7 +886,7 @@ export function diffHydratedProperties(
886 break;
887 }
888
905 - assertValidProps(tag, rawProps, getStackInDev);
889 + assertValidProps(tag, rawProps);
890
891 if (__DEV__) {
892 extraAttributeNames = new Set();
@@ -1132,7 +1116,7 @@ export function warnForDeletedHydratableElement(
1116 return;
1117 }
1118 didWarnInvalidHydration = true;
1135 - warning(
1119 + warningWithoutStack(
1120 false,
1121 'Did not expect server HTML to contain a <%s> in <%s>.',
1122 child.nodeName.toLowerCase(),
@@ -1150,7 +1134,7 @@ export function warnForDeletedHydratableText(
1134 return;
1135 }
1136 didWarnInvalidHydration = true;
1153 - warning(
1137 + warningWithoutStack(
1138 false,
1139 'Did not expect server HTML to contain the text node "%s" in <%s>.',
1140 child.nodeValue,
@@ -1169,7 +1153,7 @@ export function warnForInsertedHydratedElement(
1153 return;
1154 }
1155 didWarnInvalidHydration = true;
1172 - warning(
1156 + warningWithoutStack(
1157 false,
1158 'Expected server HTML to contain a matching <%s> in <%s>.',
1159 tag,
@@ -1194,7 +1178,7 @@ export function warnForInsertedHydratedText(
1178 return;
1179 }
1180 didWarnInvalidHydration = true;
1197 - warning(
1181 + warningWithoutStack(
1182 false,
1183 'Expected server HTML to contain a matching text node for "%s" in <%s>.',
1184 text,
packages/react-dom/src/client/ReactDOMFiberInput.js
+7 -15
@@ -8,12 +8,10 @@
8 */
9
10 // TODO: direct imports like some-package/src/* are bad. Fix me.
11 -import {
12 - getCurrentFiberOwnerNameInDevOrNull,
13 - getCurrentFiberStackInDev,
14 -} from 'react-reconciler/src/ReactCurrentFiber';
11 +import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber';
12 import invariant from 'shared/invariant';
13 import warning from 'shared/warning';
14 +import warningWithoutStack from 'shared/warningWithoutStack';
15
16 import * as DOMPropertyOperations from './DOMPropertyOperations';
17 import {getFiberCurrentPropsFromNode} from './ReactDOMComponentTree';
@@ -71,18 +69,14 @@ export function getHostProps(element: Element, props: Object) {
69
70 export function initWrapperState(element: Element, props: Object) {
71 if (__DEV__) {
74 - ReactControlledValuePropTypes.checkPropTypes(
75 - 'input',
76 - props,
77 - getCurrentFiberStackInDev,
78 - );
72 + ReactControlledValuePropTypes.checkPropTypes('input', props);
73
74 if (
75 props.checked !== undefined &&
76 props.defaultChecked !== undefined &&
77 !didWarnCheckedDefaultChecked
78 ) {
85 - warning(
79 + warningWithoutStack(
80 false,
81 '%s contains an input of type %s with both checked and defaultChecked props. ' +
82 'Input elements must be either controlled or uncontrolled ' +
@@ -100,7 +94,7 @@ export function initWrapperState(element: Element, props: Object) {
94 props.defaultValue !== undefined &&
95 !didWarnValueDefaultValue
96 ) {
103 - warning(
97 + warningWithoutStack(
98 false,
99 '%s contains an input of type %s with both value and defaultValue props. ' +
100 'Input elements must be either controlled or uncontrolled ' +
@@ -151,9 +145,8 @@ export function updateWrapper(element: Element, props: Object) {
145 'A component is changing an uncontrolled input of type %s to be controlled. ' +
146 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
147 'Decide between using a controlled or uncontrolled input ' +
154 - 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components%s',
148 + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components',
149 props.type,
156 - getCurrentFiberStackInDev(),
150 );
151 didWarnUncontrolledToControlled = true;
152 }
@@ -167,9 +160,8 @@ export function updateWrapper(element: Element, props: Object) {
160 'A component is changing a controlled input of type %s to be uncontrolled. ' +
161 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
162 'Decide between using a controlled or uncontrolled input ' +
170 - 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components%s',
163 + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components',
164 props.type,
172 - getCurrentFiberStackInDev(),
165 );
166 didWarnControlledToUncontrolled = true;
167 }
packages/react-dom/src/client/ReactDOMFiberOption.js
+2 -2
@@ -8,7 +8,7 @@
8 */
9
10 import React from 'react';
11 -import warning from 'shared/warning';
11 +import warningWithoutStack from 'shared/warningWithoutStack';
12
13 let didWarnSelectedSetOnOption = false;
14
@@ -39,7 +39,7 @@ export function validateProps(element: Element, props: Object) {
39 // TODO (yungsters): Remove support for `selected` in <option>.
40 if (__DEV__) {
41 if (props.selected != null && !didWarnSelectedSetOnOption) {
42 - warning(
42 + warningWithoutStack(
43 false,
44 'Use the `defaultValue` or `value` props on <select> instead of ' +
45 'setting `selected` on <option>.',
packages/react-dom/src/client/ReactDOMFiberSelect.js
+6 -13
@@ -8,11 +8,8 @@
8 */
9
10 // TODO: direct imports like some-package/src/* are bad. Fix me.
11 -import {
12 - getCurrentFiberOwnerNameInDevOrNull,
13 - getCurrentFiberStackInDev,
14 -} from 'react-reconciler/src/ReactCurrentFiber';
15 -import warning from 'shared/warning';
11 +import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber';
12 +import warningWithoutStack from 'shared/warningWithoutStack';
13
14 import ReactControlledValuePropTypes from '../shared/ReactControlledValuePropTypes';
15
@@ -43,11 +40,7 @@ const valuePropNames = ['value', 'defaultValue'];
40 * Validation function for `value` and `defaultValue`.
41 */
42 function checkSelectPropTypes(props) {
46 - ReactControlledValuePropTypes.checkPropTypes(
47 - 'select',
48 - props,
49 - getCurrentFiberStackInDev,
50 - );
43 + ReactControlledValuePropTypes.checkPropTypes('select', props);
44
45 for (let i = 0; i < valuePropNames.length; i++) {
46 const propName = valuePropNames[i];
@@ -56,7 +49,7 @@ function checkSelectPropTypes(props) {
49 }
50 const isArray = Array.isArray(props[propName]);
51 if (props.multiple && !isArray) {
59 - warning(
52 + warningWithoutStack(
53 false,
54 'The `%s` prop supplied to <select> must be an array if ' +
55 '`multiple` is true.%s',
@@ -64,7 +57,7 @@ function checkSelectPropTypes(props) {
57 getDeclarationErrorAddendum(),
58 );
59 } else if (!props.multiple && isArray) {
67 - warning(
60 + warningWithoutStack(
61 false,
62 'The `%s` prop supplied to <select> must be a scalar ' +
63 'value if `multiple` is false.%s',
@@ -165,7 +158,7 @@ export function initWrapperState(element: Element, props: Object) {
158 props.defaultValue !== undefined &&
159 !didWarnValueDefaultValue
160 ) {
168 - warning(
161 + warningWithoutStack(
162 false,
163 'Select elements must be either controlled or uncontrolled ' +
164 '(specify either the value prop, or the defaultValue prop, but not ' +
packages/react-dom/src/client/ReactDOMFiberTextarea.js
+4 -10
@@ -8,9 +8,7 @@
8 */
9
10 import invariant from 'shared/invariant';
11 -import warning from 'shared/warning';
12 -// TODO: direct imports like some-package/src/* are bad. Fix me.
13 -import {getCurrentFiberStackInDev} from 'react-reconciler/src/ReactCurrentFiber';
11 +import warningWithoutStack from 'shared/warningWithoutStack';
12
13 import ReactControlledValuePropTypes from '../shared/ReactControlledValuePropTypes';
14
@@ -64,17 +62,13 @@ export function getHostProps(element: Element, props: Object) {
62 export function initWrapperState(element: Element, props: Object) {
63 const node = ((element: any): TextAreaWithWrapperState);
64 if (__DEV__) {
67 - ReactControlledValuePropTypes.checkPropTypes(
68 - 'textarea',
69 - props,
70 - getCurrentFiberStackInDev,
71 - );
65 + ReactControlledValuePropTypes.checkPropTypes('textarea', props);
66 if (
67 props.value !== undefined &&
68 props.defaultValue !== undefined &&
69 !didWarnValDefaultVal
70 ) {
77 - warning(
71 + warningWithoutStack(
72 false,
73 'Textarea elements must be either controlled or uncontrolled ' +
74 '(specify either the value prop, or the defaultValue prop, but not ' +
@@ -95,7 +89,7 @@ export function initWrapperState(element: Element, props: Object) {
89 let children = props.children;
90 if (children != null) {
91 if (__DEV__) {
98 - warning(
92 + warningWithoutStack(
93 false,
94 'Use the `defaultValue` or `value` props instead of setting ' +
95 'children on <textarea>.',
packages/react-dom/src/client/validateDOMNesting.js
+4 -4
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import warning from 'shared/warning';
8 +import warningWithoutStack from 'shared/warningWithoutStack';
9 // TODO: direct imports like some-package/src/* are bad. Fix me.
10 import {getCurrentFiberStackInDev} from 'react-reconciler/src/ReactCurrentFiber';
11
@@ -407,7 +407,7 @@ if (__DEV__) {
407 const parentTag = parentInfo && parentInfo.tag;
408
409 if (childText != null) {
410 - warning(
410 + warningWithoutStack(
411 childTag == null,
412 'validateDOMNesting: when childText is passed, childTag should be null',
413 );
@@ -457,7 +457,7 @@ if (__DEV__) {
457 ' Add a <tbody> to your code to match the DOM tree generated by ' +
458 'the browser.';
459 }
460 - warning(
460 + warningWithoutStack(
461 false,
462 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s',
463 tagDisplayName,
@@ -467,7 +467,7 @@ if (__DEV__) {
467 addendum,
468 );
469 } else {
470 - warning(
470 + warningWithoutStack(
471 false,
472 'validateDOMNesting(...): %s cannot appear as a descendant of ' +
473 '<%s>.%s',
packages/react-dom/src/events/SimpleEventPlugin.js
+2 -2
@@ -22,7 +22,7 @@ import {accumulateTwoPhaseDispatches} from 'events/EventPropagators';
22 import SyntheticEvent from 'events/SyntheticEvent';
23
24 import * as DOMTopLevelEventTypes from './DOMTopLevelEventTypes';
25 -import warning from 'shared/warning';
25 +import warningWithoutStack from 'shared/warningWithoutStack';
26
27 import SyntheticAnimationEvent from './SyntheticAnimationEvent';
28 import SyntheticClipboardEvent from './SyntheticClipboardEvent';
@@ -304,7 +304,7 @@ const SimpleEventPlugin: PluginModule<MouseEvent> & {
304 default:
305 if (__DEV__) {
306 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
307 - warning(
307 + warningWithoutStack(
308 false,
309 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' +
310 'is likely caused by a bug in React. Please file an issue.',
packages/react-dom/src/server/ReactPartialRenderer.js
+21 -33
@@ -18,7 +18,7 @@ import React from 'react';
18 import invariant from 'shared/invariant';
19 import getComponentName from 'shared/getComponentName';
20 import lowPriorityWarning from 'shared/lowPriorityWarning';
21 -import warning from 'shared/warning';
21 +import warningWithoutStack from 'shared/warningWithoutStack';
22 import checkPropTypes from 'prop-types/checkPropTypes';
23 import describeComponentFrame from 'shared/describeComponentFrame';
24 import ReactSharedInternals from 'shared/ReactSharedInternals';
@@ -203,7 +203,7 @@ function createMarkupForStyles(styles): string | null {
203 const styleValue = styles[styleName];
204 if (__DEV__) {
205 if (!isCustomProperty) {
206 - warnValidStyle(styleName, styleValue, getCurrentServerStackImpl);
206 + warnValidStyle(styleName, styleValue);
207 }
208 }
209 if (styleValue != null) {
@@ -233,7 +233,7 @@ function warnNoop(
233 return;
234 }
235
236 - warning(
236 + warningWithoutStack(
237 false,
238 '%s(...): Can only update a mounting component. ' +
239 'This usually means you called %s() outside componentWillMount() on the server. ' +
@@ -298,7 +298,7 @@ function flattenOptionChildren(children: mixed): ?string {
298 if (__DEV__) {
299 if (!didWarnInvalidOptionChildren) {
300 didWarnInvalidOptionChildren = true;
301 - warning(
301 + warningWithoutStack(
302 false,
303 'Only strings and numbers are supported as <option> children.',
304 );
@@ -472,7 +472,7 @@ function resolve(
472 if (inst.state === null || inst.state === undefined) {
473 const componentName = getComponentName(Component) || 'Unknown';
474 if (!didWarnAboutUninitializedState[componentName]) {
475 - warning(
475 + warningWithoutStack(
476 false,
477 '%s: Did not properly initialize state during construction. ' +
478 'Expected state to be an object, but it was %s.',
@@ -494,7 +494,7 @@ function resolve(
494 if (partialState === undefined) {
495 const componentName = getComponentName(Component) || 'Unknown';
496 if (!didWarnAboutUndefinedDerivedState[componentName]) {
497 - warning(
497 + warningWithoutStack(
498 false,
499 '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' +
500 'You have returned undefined.',
@@ -518,7 +518,7 @@ function resolve(
518 const componentName = getComponentName(Component) || 'Unknown';
519
520 if (!didWarnAboutBadClass[componentName]) {
521 - warning(
521 + warningWithoutStack(
522 false,
523 "The <%s /> component appears to have a render method, but doesn't extend React.Component. " +
524 'This is likely to cause errors. Change %s to extend React.Component instead.',
@@ -645,7 +645,7 @@ function resolve(
645 );
646 }
647 } else {
648 - warning(
648 + warningWithoutStack(
649 false,
650 '%s.getChildContext(): childContextTypes must be defined in order to ' +
651 'use getChildContext().',
@@ -747,7 +747,7 @@ class ReactDOMServerRenderer {
747 popProvider<T>(provider: ReactProvider<T>): void {
748 const index = this.contextIndex;
749 if (__DEV__) {
750 - warning(
750 + warningWithoutStack(
751 index > -1 && provider === (this.contextProviderStack: any)[index],
752 'Unexpected pop.',
753 );
@@ -1022,7 +1022,7 @@ class ReactDOMServerRenderer {
1022 if (namespace === Namespaces.html) {
1023 // Should this check be gated by parent namespace? Not sure we want to
1024 // allow <SVG> or <mATH>.
1025 - warning(
1025 + warningWithoutStack(
1026 tag === element.type,
1027 '<%s /> is using incorrect casing. ' +
1028 'Use PascalCase for React components, ' +
@@ -1037,18 +1037,14 @@ class ReactDOMServerRenderer {
1037 let props = element.props;
1038 if (tag === 'input') {
1039 if (__DEV__) {
1040 - ReactControlledValuePropTypes.checkPropTypes(
1041 - 'input',
1042 - props,
1043 - getCurrentServerStackImpl,
1044 - );
1040 + ReactControlledValuePropTypes.checkPropTypes('input', props);
1041
1042 if (
1043 props.checked !== undefined &&
1044 props.defaultChecked !== undefined &&
1045 !didWarnDefaultChecked
1046 ) {
1051 - warning(
1047 + warningWithoutStack(
1048 false,
1049 '%s contains an input of type %s with both checked and defaultChecked props. ' +
1050 'Input elements must be either controlled or uncontrolled ' +
@@ -1066,7 +1062,7 @@ class ReactDOMServerRenderer {
1062 props.defaultValue !== undefined &&
1063 !didWarnDefaultInputValue
1064 ) {
1069 - warning(
1065 + warningWithoutStack(
1066 false,
1067 '%s contains an input of type %s with both value and defaultValue props. ' +
1068 'Input elements must be either controlled or uncontrolled ' +
@@ -1095,17 +1091,13 @@ class ReactDOMServerRenderer {
1091 );
1092 } else if (tag === 'textarea') {
1093 if (__DEV__) {
1098 - ReactControlledValuePropTypes.checkPropTypes(
1099 - 'textarea',
1100 - props,
1101 - getCurrentServerStackImpl,
1102 - );
1094 + ReactControlledValuePropTypes.checkPropTypes('textarea', props);
1095 if (
1096 props.value !== undefined &&
1097 props.defaultValue !== undefined &&
1098 !didWarnDefaultTextareaValue
1099 ) {
1108 - warning(
1100 + warningWithoutStack(
1101 false,
1102 'Textarea elements must be either controlled or uncontrolled ' +
1103 '(specify either the value prop, or the defaultValue prop, but not ' +
@@ -1124,7 +1116,7 @@ class ReactDOMServerRenderer {
1116 let textareaChildren = props.children;
1117 if (textareaChildren != null) {
1118 if (__DEV__) {
1127 - warning(
1119 + warningWithoutStack(
1120 false,
1121 'Use the `defaultValue` or `value` props instead of setting ' +
1122 'children on <textarea>.',
@@ -1156,11 +1148,7 @@ class ReactDOMServerRenderer {
1148 });
1149 } else if (tag === 'select') {
1150 if (__DEV__) {
1159 - ReactControlledValuePropTypes.checkPropTypes(
1160 - 'select',
1161 - props,
1162 - getCurrentServerStackImpl,
1163 - );
1151 + ReactControlledValuePropTypes.checkPropTypes('select', props);
1152
1153 for (let i = 0; i < valuePropNames.length; i++) {
1154 const propName = valuePropNames[i];
@@ -1169,7 +1157,7 @@ class ReactDOMServerRenderer {
1157 }
1158 const isArray = Array.isArray(props[propName]);
1159 if (props.multiple && !isArray) {
1172 - warning(
1160 + warningWithoutStack(
1161 false,
1162 'The `%s` prop supplied to <select> must be an array if ' +
1163 '`multiple` is true.%s',
@@ -1177,7 +1165,7 @@ class ReactDOMServerRenderer {
1165 '', // getDeclarationErrorAddendum(),
1166 );
1167 } else if (!props.multiple && isArray) {
1180 - warning(
1168 + warningWithoutStack(
1169 false,
1170 'The `%s` prop supplied to <select> must be a scalar ' +
1171 'value if `multiple` is false.%s',
@@ -1192,7 +1180,7 @@ class ReactDOMServerRenderer {
1180 props.defaultValue !== undefined &&
1181 !didWarnDefaultSelectValue
1182 ) {
1195 - warning(
1183 + warningWithoutStack(
1184 false,
1185 'Select elements must be either controlled or uncontrolled ' +
1186 '(specify either the value prop, or the defaultValue prop, but not ' +
@@ -1250,7 +1238,7 @@ class ReactDOMServerRenderer {
1238 validatePropertiesInDevelopment(tag, props);
1239 }
1240
1253 - assertValidProps(tag, props, getCurrentServerStackImpl);
1241 + assertValidProps(tag, props);
1242
1243 let out = createOpenTagMarkup(
1244 element.type,
packages/react-dom/src/shared/CSSPropertyOperations.js
+2 -2
@@ -51,7 +51,7 @@ export function createDangerousStringForStyles(styles) {
51 * @param {DOMElement} node
52 * @param {object} styles
53 */
54 -export function setValueForStyles(node, styles, getStack) {
54 +export function setValueForStyles(node, styles) {
55 const style = node.style;
56 for (let styleName in styles) {
57 if (!styles.hasOwnProperty(styleName)) {
@@ -60,7 +60,7 @@ export function setValueForStyles(node, styles, getStack) {
60 const isCustomProperty = styleName.indexOf('--') === 0;
61 if (__DEV__) {
62 if (!isCustomProperty) {
63 - warnValidStyle(styleName, styles[styleName], getStack);
63 + warnValidStyle(styleName, styles[styleName]);
64 }
65 }
66 const styleValue = dangerousStyleValue(
packages/react-dom/src/shared/DOMProperty.js
+2 -2
@@ -7,7 +7,7 @@
7 * @flow
8 */
9
10 -import warning from 'shared/warning';
10 +import warningWithoutStack from 'shared/warningWithoutStack';
11
12 type PropertyType = 0 | 1 | 2 | 3 | 4 | 5 | 6;
13
@@ -82,7 +82,7 @@ export function isAttributeNameSafe(attributeName: string): boolean {
82 }
83 illegalAttributeNameCache[attributeName] = true;
84 if (__DEV__) {
85 - warning(false, 'Invalid attribute name: `%s`', attributeName);
85 + warningWithoutStack(false, 'Invalid attribute name: `%s`', attributeName);
86 }
87 return false;
88 }
packages/react-dom/src/shared/ReactControlledValuePropTypes.js
+13 -6
@@ -6,12 +6,17 @@
6 */
7
8 import checkPropTypes from 'prop-types/checkPropTypes';
9 +import ReactSharedInternals from 'shared/ReactSharedInternals';
10 +
11 +let ReactDebugCurrentFrame = null;
12
13 const ReactControlledValuePropTypes = {
14 checkPropTypes: null,
15 };
16
17 if (__DEV__) {
18 + ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
19 +
20 const hasReadOnlyValue = {
21 button: true,
22 checkbox: true,
@@ -62,12 +67,14 @@ if (__DEV__) {
67 * Provide a linked `value` attribute for controlled forms. You should not use
68 * this outside of the ReactDOM controlled form components.
69 */
65 - ReactControlledValuePropTypes.checkPropTypes = function(
66 - tagName,
67 - props,
68 - getStack,
69 - ) {
70 - checkPropTypes(propTypes, props, 'prop', tagName, getStack);
70 + ReactControlledValuePropTypes.checkPropTypes = function(tagName, props) {
71 + checkPropTypes(
72 + propTypes,
73 + props,
74 + 'prop',
75 + tagName,
76 + ReactDebugCurrentFrame.getStackAddendum,
77 + );
78 };
79 }
80
packages/react-dom/src/shared/ReactDOMInvalidARIAHook.js
+5 -13
@@ -6,14 +6,11 @@
6 */
7
8 import warning from 'shared/warning';
9 -import ReactSharedInternals from 'shared/ReactSharedInternals';
9
10 import {ATTRIBUTE_NAME_CHAR} from './DOMProperty';
11 import isCustomComponent from './isCustomComponent';
12 import validAriaProperties from './validAriaProperties';
13
15 -const ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
16 -
14 const warnedProperties = {};
15 const rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
16 const rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
@@ -36,9 +33,8 @@ function validateProperty(tagName, name) {
33 if (correctName == null) {
34 warning(
35 false,
39 - 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.%s',
36 + 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.',
37 name,
41 - ReactDebugCurrentFrame.getStackAddendum(),
38 );
39 warnedProperties[name] = true;
40 return true;
@@ -47,10 +43,9 @@ function validateProperty(tagName, name) {
43 if (name !== correctName) {
44 warning(
45 false,
50 - 'Invalid ARIA attribute `%s`. Did you mean `%s`?%s',
46 + 'Invalid ARIA attribute `%s`. Did you mean `%s`?',
47 name,
48 correctName,
53 - ReactDebugCurrentFrame.getStackAddendum(),
49 );
50 warnedProperties[name] = true;
51 return true;
@@ -73,10 +68,9 @@ function validateProperty(tagName, name) {
68 if (name !== standardName) {
69 warning(
70 false,
76 - 'Unknown ARIA attribute `%s`. Did you mean `%s`?%s',
71 + 'Unknown ARIA attribute `%s`. Did you mean `%s`?',
72 name,
73 standardName,
79 - ReactDebugCurrentFrame.getStackAddendum(),
74 );
75 warnedProperties[name] = true;
76 return true;
@@ -104,19 +98,17 @@ function warnInvalidARIAProps(type, props) {
98 warning(
99 false,
100 'Invalid aria prop %s on <%s> tag. ' +
107 - 'For details, see https://fb.me/invalid-aria-prop%s',
101 + 'For details, see https://fb.me/invalid-aria-prop',
102 unknownPropString,
103 type,
110 - ReactDebugCurrentFrame.getStackAddendum(),
104 );
105 } else if (invalidProps.length > 1) {
106 warning(
107 false,
108 'Invalid aria props %s on <%s> tag. ' +
116 - 'For details, see https://fb.me/invalid-aria-prop%s',
109 + 'For details, see https://fb.me/invalid-aria-prop',
110 unknownPropString,
111 type,
119 - ReactDebugCurrentFrame.getStackAddendum(),
112 );
113 }
114 }
packages/react-dom/src/shared/ReactDOMNullInputValuePropHook.js
+2 -7
@@ -5,11 +5,8 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import ReactSharedInternals from 'shared/ReactSharedInternals';
8 import warning from 'shared/warning';
9
11 -let ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
12 -
10 let didWarnValueNull = false;
11
12 export function validateProperties(type, props) {
@@ -24,18 +21,16 @@ export function validateProperties(type, props) {
21 false,
22 '`value` prop on `%s` should not be null. ' +
23 'Consider using an empty array when `multiple` is set to `true` ' +
27 - 'to clear the component or `undefined` for uncontrolled components.%s',
24 + 'to clear the component or `undefined` for uncontrolled components.',
25 type,
29 - ReactDebugCurrentFrame.getStackAddendum(),
26 );
27 } else {
28 warning(
29 false,
30 '`value` prop on `%s` should not be null. ' +
31 'Consider using an empty string to clear the component or `undefined` ' +
36 - 'for uncontrolled components.%s',
32 + 'for uncontrolled components.',
33 type,
38 - ReactDebugCurrentFrame.getStackAddendum(),
34 );
35 }
36 }
packages/react-dom/src/shared/ReactDOMUnknownPropertyHook.js
+15 -30
@@ -9,8 +9,8 @@ import {
9 registrationNameModules,
10 possibleRegistrationNames,
11 } from 'events/EventPluginRegistry';
12 -import ReactSharedInternals from 'shared/ReactSharedInternals';
12 import warning from 'shared/warning';
13 +import warningWithoutStack from 'shared/warningWithoutStack';
14
15 import {
16 ATTRIBUTE_NAME_CHAR,
@@ -21,13 +21,9 @@ import {
21 import isCustomComponent from './isCustomComponent';
22 import possibleStandardNames from './possibleStandardNames';
23
24 -let ReactDebugCurrentFrame = null;
25 -
24 let validateProperty = () => {};
25
26 if (__DEV__) {
29 - ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
30 -
27 const warnedProperties = {};
28 const hasOwnProperty = Object.prototype.hasOwnProperty;
29 const EVENT_NAME_REGEX = /^on./;
@@ -42,7 +38,7 @@ if (__DEV__) {
38
39 const lowerCasedName = name.toLowerCase();
40 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
45 - warning(
41 + warningWithoutStack(
42 false,
43 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' +
44 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' +
@@ -65,10 +61,9 @@ if (__DEV__) {
61 if (registrationName != null) {
62 warning(
63 false,
68 - 'Invalid event handler property `%s`. Did you mean `%s`?%s',
64 + 'Invalid event handler property `%s`. Did you mean `%s`?',
65 name,
66 registrationName,
71 - ReactDebugCurrentFrame.getStackAddendum(),
67 );
68 warnedProperties[name] = true;
69 return true;
@@ -76,9 +71,8 @@ if (__DEV__) {
71 if (EVENT_NAME_REGEX.test(name)) {
72 warning(
73 false,
79 - 'Unknown event handler property `%s`. It will be ignored.%s',
74 + 'Unknown event handler property `%s`. It will be ignored.',
75 name,
81 - ReactDebugCurrentFrame.getStackAddendum(),
76 );
77 warnedProperties[name] = true;
78 return true;
@@ -91,9 +85,8 @@ if (__DEV__) {
85 warning(
86 false,
87 'Invalid event handler property `%s`. ' +
94 - 'React events use the camelCase naming convention, for example `onClick`.%s',
88 + 'React events use the camelCase naming convention, for example `onClick`.',
89 name,
96 - ReactDebugCurrentFrame.getStackAddendum(),
90 );
91 }
92 warnedProperties[name] = true;
@@ -106,7 +99,7 @@ if (__DEV__) {
99 }
100
101 if (lowerCasedName === 'innerhtml') {
109 - warning(
102 + warningWithoutStack(
103 false,
104 'Directly setting property `innerHTML` is not permitted. ' +
105 'For more information, lookup documentation on `dangerouslySetInnerHTML`.',
@@ -116,7 +109,7 @@ if (__DEV__) {
109 }
110
111 if (lowerCasedName === 'aria') {
119 - warning(
112 + warningWithoutStack(
113 false,
114 'The `aria` attribute is reserved for future use in React. ' +
115 'Pass individual `aria-` attributes instead.',
@@ -134,9 +127,8 @@ if (__DEV__) {
127 warning(
128 false,
129 'Received a `%s` for a string attribute `is`. If this is expected, cast ' +
137 - 'the value to a string.%s',
130 + 'the value to a string.',
131 typeof value,
139 - ReactDebugCurrentFrame.getStackAddendum(),
132 );
133 warnedProperties[name] = true;
134 return true;
@@ -146,9 +138,8 @@ if (__DEV__) {
138 warning(
139 false,
140 'Received NaN for the `%s` attribute. If this is expected, cast ' +
149 - 'the value to a string.%s',
141 + 'the value to a string.',
142 name,
151 - ReactDebugCurrentFrame.getStackAddendum(),
143 );
144 warnedProperties[name] = true;
145 return true;
@@ -163,10 +154,9 @@ if (__DEV__) {
154 if (standardName !== name) {
155 warning(
156 false,
166 - 'Invalid DOM property `%s`. Did you mean `%s`?%s',
157 + 'Invalid DOM property `%s`. Did you mean `%s`?',
158 name,
159 standardName,
169 - ReactDebugCurrentFrame.getStackAddendum(),
160 );
161 warnedProperties[name] = true;
162 return true;
@@ -180,10 +170,9 @@ if (__DEV__) {
170 'intentionally want it to appear in the DOM as a custom ' +
171 'attribute, spell it as lowercase `%s` instead. ' +
172 'If you accidentally passed it from a parent component, remove ' +
183 - 'it from the DOM element.%s',
173 + 'it from the DOM element.',
174 name,
175 lowerCasedName,
186 - ReactDebugCurrentFrame.getStackAddendum(),
176 );
177 warnedProperties[name] = true;
178 return true;
@@ -198,13 +187,12 @@ if (__DEV__) {
187 false,
188 'Received `%s` for a non-boolean attribute `%s`.\n\n' +
189 'If you want to write it to the DOM, pass a string instead: ' +
201 - '%s="%s" or %s={value.toString()}.%s',
190 + '%s="%s" or %s={value.toString()}.',
191 value,
192 name,
193 name,
194 value,
195 name,
207 - ReactDebugCurrentFrame.getStackAddendum(),
196 );
197 } else {
198 warning(
@@ -213,7 +201,7 @@ if (__DEV__) {
201 'If you want to write it to the DOM, pass a string instead: ' +
202 '%s="%s" or %s={value.toString()}.\n\n' +
203 'If you used to conditionally omit it with %s={condition && value}, ' +
216 - 'pass %s={condition ? value : undefined} instead.%s',
204 + 'pass %s={condition ? value : undefined} instead.',
205 value,
206 name,
207 name,
@@ -221,7 +209,6 @@ if (__DEV__) {
209 name,
210 name,
211 name,
224 - ReactDebugCurrentFrame.getStackAddendum(),
212 );
213 }
214 warnedProperties[name] = true;
@@ -261,20 +248,18 @@ const warnUnknownProperties = function(type, props, canUseEventSystem) {
248 false,
249 'Invalid value for prop %s on <%s> tag. Either remove it from the element, ' +
250 'or pass a string or number value to keep it in the DOM. ' +
264 - 'For details, see https://fb.me/react-attribute-behavior%s',
251 + 'For details, see https://fb.me/react-attribute-behavior',
252 unknownPropString,
253 type,
267 - ReactDebugCurrentFrame.getStackAddendum(),
254 );
255 } else if (unknownProps.length > 1) {
256 warning(
257 false,
258 'Invalid values for props %s on <%s> tag. Either remove them from the element, ' +
259 'or pass a string or number value to keep them in the DOM. ' +
274 - 'For details, see https://fb.me/react-attribute-behavior%s',
260 + 'For details, see https://fb.me/react-attribute-behavior',
261 unknownPropString,
262 type,
277 - ReactDebugCurrentFrame.getStackAddendum(),
263 );
264 }
265 };
packages/react-dom/src/shared/assertValidProps.js
+12 -5
@@ -7,12 +7,20 @@
7
8 import invariant from 'shared/invariant';
9 import warning from 'shared/warning';
10 +// TODO: We can remove this if we add invariantWithStack()
11 +// or add stack by default to invariants where possible.
12 +import ReactSharedInternals from 'shared/ReactSharedInternals';
13
14 import voidElementTags from './voidElementTags';
15
16 const HTML = '__html';
17
15 -function assertValidProps(tag: string, props: ?Object, getStack: () => string) {
18 +let ReactDebugCurrentFrame = null;
19 +if (__DEV__) {
20 + ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
21 +}
22 +
23 +function assertValidProps(tag: string, props: ?Object) {
24 if (!props) {
25 return;
26 }
@@ -23,7 +31,7 @@ function assertValidProps(tag: string, props: ?Object, getStack: () => string) {
31 '%s is a void element tag and must neither have `children` nor ' +
32 'use `dangerouslySetInnerHTML`.%s',
33 tag,
26 - getStack(),
34 + __DEV__ ? ReactDebugCurrentFrame.getStackAddendum() : '',
35 );
36 }
37 if (props.dangerouslySetInnerHTML != null) {
@@ -47,8 +55,7 @@ function assertValidProps(tag: string, props: ?Object, getStack: () => string) {
55 'A component is `contentEditable` and contains `children` managed by ' +
56 'React. It is now your responsibility to guarantee that none of ' +
57 'those nodes are unexpectedly modified or duplicated. This is ' +
50 - 'probably not intentional.%s',
51 - getStack(),
58 + 'probably not intentional.',
59 );
60 }
61 invariant(
@@ -56,7 +63,7 @@ function assertValidProps(tag: string, props: ?Object, getStack: () => string) {
63 'The `style` prop expects a mapping from style properties to values, ' +
64 "not a string. For example, style={{marginRight: spacing + 'em'}} when " +
65 'using JSX.%s',
59 - getStack(),
66 + __DEV__ ? ReactDebugCurrentFrame.getStackAddendum() : '',
67 );
68 }
69
packages/react-dom/src/shared/warnValidStyle.js
+16 -21
@@ -29,7 +29,7 @@ if (__DEV__) {
29 });
30 };
31
32 - const warnHyphenatedStyleName = function(name, getStack) {
32 + const warnHyphenatedStyleName = function(name) {
33 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
34 return;
35 }
@@ -37,17 +37,16 @@ if (__DEV__) {
37 warnedStyleNames[name] = true;
38 warning(
39 false,
40 - 'Unsupported style property %s. Did you mean %s?%s',
40 + 'Unsupported style property %s. Did you mean %s?',
41 name,
42 // As Andi Smith suggests
43 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
44 // is converted to lowercase `ms`.
45 camelize(name.replace(msPattern, 'ms-')),
46 - getStack(),
46 );
47 };
48
50 - const warnBadVendoredStyleName = function(name, getStack) {
49 + const warnBadVendoredStyleName = function(name) {
50 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
51 return;
52 }
@@ -55,14 +54,13 @@ if (__DEV__) {
54 warnedStyleNames[name] = true;
55 warning(
56 false,
58 - 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s',
57 + 'Unsupported vendor-prefixed style property %s. Did you mean %s?',
58 name,
59 name.charAt(0).toUpperCase() + name.slice(1),
61 - getStack(),
60 );
61 };
62
65 - const warnStyleValueWithSemicolon = function(name, value, getStack) {
63 + const warnStyleValueWithSemicolon = function(name, value) {
64 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
65 return;
66 }
@@ -71,14 +69,13 @@ if (__DEV__) {
69 warning(
70 false,
71 "Style property values shouldn't contain a semicolon. " +
74 - 'Try "%s: %s" instead.%s',
72 + 'Try "%s: %s" instead.',
73 name,
74 value.replace(badStyleValueWithSemicolonPattern, ''),
77 - getStack(),
75 );
76 };
77
81 - const warnStyleValueIsNaN = function(name, value, getStack) {
78 + const warnStyleValueIsNaN = function(name, value) {
79 if (warnedForNaNValue) {
80 return;
81 }
@@ -86,13 +83,12 @@ if (__DEV__) {
83 warnedForNaNValue = true;
84 warning(
85 false,
89 - '`NaN` is an invalid value for the `%s` css style property.%s',
86 + '`NaN` is an invalid value for the `%s` css style property.',
87 name,
91 - getStack(),
88 );
89 };
90
95 - const warnStyleValueIsInfinity = function(name, value, getStack) {
91 + const warnStyleValueIsInfinity = function(name, value) {
92 if (warnedForInfinityValue) {
93 return;
94 }
@@ -100,26 +96,25 @@ if (__DEV__) {
96 warnedForInfinityValue = true;
97 warning(
98 false,
103 - '`Infinity` is an invalid value for the `%s` css style property.%s',
99 + '`Infinity` is an invalid value for the `%s` css style property.',
100 name,
105 - getStack(),
101 );
102 };
103
109 - warnValidStyle = function(name, value, getStack) {
104 + warnValidStyle = function(name, value) {
105 if (name.indexOf('-') > -1) {
111 - warnHyphenatedStyleName(name, getStack);
106 + warnHyphenatedStyleName(name);
107 } else if (badVendoredStyleNamePattern.test(name)) {
113 - warnBadVendoredStyleName(name, getStack);
108 + warnBadVendoredStyleName(name);
109 } else if (badStyleValueWithSemicolonPattern.test(value)) {
115 - warnStyleValueWithSemicolon(name, value, getStack);
110 + warnStyleValueWithSemicolon(name, value);
111 }
112
113 if (typeof value === 'number') {
114 if (isNaN(value)) {
120 - warnStyleValueIsNaN(name, value, getStack);
115 + warnStyleValueIsNaN(name, value);
116 } else if (!isFinite(value)) {
122 - warnStyleValueIsInfinity(name, value, getStack);
117 + warnStyleValueIsInfinity(name, value);
118 }
119 }
120 };
packages/react-native-renderer/src/ReactFabric.js
+2 -2
@@ -25,7 +25,7 @@ import {getInspectorDataForViewTag} from './ReactNativeFiberInspector';
25
26 import ReactSharedInternals from 'shared/ReactSharedInternals';
27 import getComponentName from 'shared/getComponentName';
28 -import warning from 'shared/warning';
28 +import warningWithoutStack from 'shared/warningWithoutStack';
29
30 const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
31 const findHostInstance = ReactFabricRenderer.findHostInstance;
@@ -34,7 +34,7 @@ function findNodeHandle(componentOrHandle: any): ?number {
34 if (__DEV__) {
35 const owner = ReactCurrentOwner.current;
36 if (owner !== null && owner.stateNode !== null) {
37 - warning(
37 + warningWithoutStack(
38 owner.stateNode._warnedAboutRefsInRender,
39 '%s is accessing findNodeHandle inside its render(). ' +
40 'render() should be a pure function of props and state. It should ' +
packages/react-native-renderer/src/ReactNativeEventEmitter.js
+2 -2
@@ -10,7 +10,7 @@
10 import {getListener, runExtractedEventsInBatch} from 'events/EventPluginHub';
11 import {registrationNameModules} from 'events/EventPluginRegistry';
12 import {batchedUpdates} from 'events/ReactGenericBatching';
13 -import warning from 'shared/warning';
13 +import warningWithoutStack from 'shared/warningWithoutStack';
14
15 import {getInstanceFromNode} from './ReactNativeComponentTree';
16
@@ -168,7 +168,7 @@ export function receiveTouches(
168 if (target !== null && target !== undefined) {
169 if (target < 1) {
170 if (__DEV__) {
171 - warning(
171 + warningWithoutStack(
172 false,
173 'A view is reporting that a touch occurred on tag zero.',
174 );
packages/react-native-renderer/src/ReactNativeRenderer.js
+2 -2
@@ -28,7 +28,7 @@ import {getInspectorDataForViewTag} from './ReactNativeFiberInspector';
28
29 import ReactSharedInternals from 'shared/ReactSharedInternals';
30 import getComponentName from 'shared/getComponentName';
31 -import warning from 'shared/warning';
31 +import warningWithoutStack from 'shared/warningWithoutStack';
32
33 const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
34 const findHostInstance = ReactNativeFiberRenderer.findHostInstance;
@@ -37,7 +37,7 @@ function findNodeHandle(componentOrHandle: any): ?number {
37 if (__DEV__) {
38 const owner = ReactCurrentOwner.current;
39 if (owner !== null && owner.stateNode !== null) {
40 - warning(
40 + warningWithoutStack(
41 owner.stateNode._warnedAboutRefsInRender,
42 '%s is accessing findNodeHandle inside its render(). ' +
43 'render() should be a pure function of props and state. It should ' +
packages/react-reconciler/src/ReactChildFiber.js
+6 -9
@@ -29,6 +29,7 @@ import {
29 } from 'shared/ReactTypeOfWork';
30 import invariant from 'shared/invariant';
31 import warning from 'shared/warning';
32 +import warningWithoutStack from 'shared/warningWithoutStack';
33
34 import {
35 createWorkInProgress,
@@ -90,8 +91,7 @@ if (__DEV__) {
91 false,
92 'Each child in an array or iterator should have a unique ' +
93 '"key" prop. See https://fb.me/react-warning-keys for ' +
93 - 'more information.%s',
94 - getCurrentFiberStackInDev(),
94 + 'more information.',
95 );
96 };
97 }
@@ -113,7 +113,7 @@ function coerceRef(
113 if (returnFiber.mode & StrictMode) {
114 const componentName = getComponentName(returnFiber.type) || 'Component';
115 if (!didWarnAboutStringRefInStrictMode[componentName]) {
116 - warning(
116 + warningWithoutStack(
117 false,
118 'A string ref, "%s", has been found within a strict mode tree. ' +
119 'String refs are a source of potential bugs and should be avoided. ' +
@@ -226,8 +226,7 @@ function warnOnFunctionType() {
226 false,
227 'Functions are not valid as a React child. This may happen if ' +
228 'you return a Component instead of <Component /> from render. ' +
229 - 'Or maybe you meant to call this function rather than return it.%s',
230 - getCurrentFiberStackInDev(),
229 + 'Or maybe you meant to call this function rather than return it.',
230 );
231 }
232
@@ -717,9 +716,8 @@ function ChildReconciler(shouldTrackSideEffects) {
716 'Keys should be unique so that components maintain their identity ' +
717 'across updates. Non-unique keys may cause children to be ' +
718 'duplicated and/or omitted — the behavior is unsupported and ' +
720 - 'could change in a future version.%s',
719 + 'could change in a future version.',
720 key,
722 - getCurrentFiberStackInDev(),
721 );
722 break;
723 default:
@@ -911,8 +909,7 @@ function ChildReconciler(shouldTrackSideEffects) {
909 didWarnAboutMaps,
910 'Using Maps as children is unsupported and will likely yield ' +
911 'unexpected results. Convert it to a sequence/iterable of keyed ' +
914 - 'ReactElements instead.%s',
915 - getCurrentFiberStackInDev(),
912 + 'ReactElements instead.',
913 );
914 didWarnAboutMaps = true;
915 }
packages/react-reconciler/src/ReactFiberBeginWork.js
+7 -7
@@ -50,6 +50,7 @@ import invariant from 'shared/invariant';
50 import getComponentName from 'shared/getComponentName';
51 import ReactStrictModeWarnings from './ReactStrictModeWarnings';
52 import warning from 'shared/warning';
53 +import warningWithoutStack from 'shared/warningWithoutStack';
54 import * as ReactCurrentFiber from './ReactCurrentFiber';
55 import {cancelWorkTimer} from './ReactDebugFiberPerf';
56
@@ -586,7 +587,7 @@ function mountIndeterminateComponent(
587 const componentName = getComponentName(fn) || 'Unknown';
588
589 if (!didWarnAboutBadClass[componentName]) {
589 - warning(
590 + warningWithoutStack(
591 false,
592 "The <%s /> component appears to have a render method, but doesn't extend React.Component. " +
593 'This is likely to cause errors. Change %s to extend React.Component instead.',
@@ -652,7 +653,7 @@ function mountIndeterminateComponent(
653 const Component = workInProgress.type;
654
655 if (Component) {
655 - warning(
656 + warningWithoutStack(
657 !Component.childContextTypes,
658 '%s(...): childContextTypes cannot be defined on a functional component.',
659 Component.displayName || Component.name || 'Component',
@@ -675,9 +676,8 @@ function mountIndeterminateComponent(
676 warning(
677 false,
678 'Stateless function components cannot be given refs. ' +
678 - 'Attempts to access this ref will fail.%s%s',
679 + 'Attempts to access this ref will fail.%s',
680 info,
680 - ReactCurrentFiber.getCurrentFiberStackInDev(),
681 );
682 }
683 }
@@ -686,7 +686,7 @@ function mountIndeterminateComponent(
686 const componentName = getComponentName(fn) || 'Unknown';
687
688 if (!didWarnAboutGetDerivedStateOnFunctionalComponent[componentName]) {
689 - warning(
689 + warningWithoutStack(
690 false,
691 '%s: Stateless functional components do not support getDerivedStateFromProps.',
692 componentName,
@@ -976,7 +976,7 @@ function updateContextProvider(current, workInProgress, renderExpirationTime) {
976 ? context._calculateChangedBits(oldValue, newValue)
977 : MAX_SIGNED_31_BIT_INT;
978 if (__DEV__) {
979 - warning(
979 + warningWithoutStack(
980 (changedBits & MAX_SIGNED_31_BIT_INT) === changedBits,
981 'calculateChangedBits: Expected the return value to be a ' +
982 '31-bit integer. Instead received: %s',
@@ -1057,7 +1057,7 @@ function updateContextConsumer(current, workInProgress, renderExpirationTime) {
1057 const render = newProps.children;
1058
1059 if (__DEV__) {
1060 - warning(
1060 + warningWithoutStack(
1061 typeof render === 'function',
1062 'A context consumer was rendered with multiple children, or a child ' +
1063 "that isn't a function. A context consumer expects a single child " +
packages/react-reconciler/src/ReactFiberClassComponent.js
+32 -28
@@ -23,7 +23,7 @@ import * as ReactInstanceMap from 'shared/ReactInstanceMap';
23 import shallowEqual from 'shared/shallowEqual';
24 import getComponentName from 'shared/getComponentName';
25 import invariant from 'shared/invariant';
26 -import warning from 'shared/warning';
26 +import warningWithoutStack from 'shared/warningWithoutStack';
27
28 import {startPhaseTimer, stopPhaseTimer} from './ReactDebugFiberPerf';
29 import {StrictMode} from './ReactTypeOfMode';
@@ -82,7 +82,7 @@ if (__DEV__) {
82 const key = `${callerName}_${(callback: any)}`;
83 if (!didWarnOnInvalidCallback.has(key)) {
84 didWarnOnInvalidCallback.add(key);
85 - warning(
85 + warningWithoutStack(
86 false,
87 '%s(...): Expected the last optional `callback` argument to be a ' +
88 'function. Instead received: %s.',
@@ -97,7 +97,7 @@ if (__DEV__) {
97 const componentName = getComponentName(type) || 'Component';
98 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
99 didWarnAboutUndefinedDerivedState.add(componentName);
100 - warning(
100 + warningWithoutStack(
101 false,
102 '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' +
103 'You have returned undefined.',
@@ -245,7 +245,7 @@ function checkShouldComponentUpdate(
245 stopPhaseTimer();
246
247 if (__DEV__) {
248 - warning(
248 + warningWithoutStack(
249 shouldUpdate !== undefined,
250 '%s.shouldComponentUpdate(): Returned undefined instead of a ' +
251 'boolean value. Make sure to return true or false.',
@@ -274,14 +274,14 @@ function checkClassInstance(workInProgress: Fiber) {
274
275 if (!renderPresent) {
276 if (type.prototype && typeof type.prototype.render === 'function') {
277 - warning(
277 + warningWithoutStack(
278 false,
279 '%s(...): No `render` method found on the returned component ' +
280 'instance: did you accidentally return an object from the constructor?',
281 name,
282 );
283 } else {
284 - warning(
284 + warningWithoutStack(
285 false,
286 '%s(...): No `render` method found on the returned component ' +
287 'instance: you may have forgotten to define `render`.',
@@ -294,7 +294,7 @@ function checkClassInstance(workInProgress: Fiber) {
294 !instance.getInitialState ||
295 instance.getInitialState.isReactClassApproved ||
296 instance.state;
297 - warning(
297 + warningWithoutStack(
298 noGetInitialStateOnES6,
299 'getInitialState was defined on %s, a plain JavaScript class. ' +
300 'This is only supported for classes created using React.createClass. ' +
@@ -304,7 +304,7 @@ function checkClassInstance(workInProgress: Fiber) {
304 const noGetDefaultPropsOnES6 =
305 !instance.getDefaultProps ||
306 instance.getDefaultProps.isReactClassApproved;
307 - warning(
307 + warningWithoutStack(
308 noGetDefaultPropsOnES6,
309 'getDefaultProps was defined on %s, a plain JavaScript class. ' +
310 'This is only supported for classes created using React.createClass. ' +
@@ -312,14 +312,14 @@ function checkClassInstance(workInProgress: Fiber) {
312 name,
313 );
314 const noInstancePropTypes = !instance.propTypes;
315 - warning(
315 + warningWithoutStack(
316 noInstancePropTypes,
317 'propTypes was defined as an instance property on %s. Use a static ' +
318 'property to define propTypes instead.',
319 name,
320 );
321 const noInstanceContextTypes = !instance.contextTypes;
322 - warning(
322 + warningWithoutStack(
323 noInstanceContextTypes,
324 'contextTypes was defined as an instance property on %s. Use a static ' +
325 'property to define contextTypes instead.',
@@ -327,7 +327,7 @@ function checkClassInstance(workInProgress: Fiber) {
327 );
328 const noComponentShouldUpdate =
329 typeof instance.componentShouldUpdate !== 'function';
330 - warning(
330 + warningWithoutStack(
331 noComponentShouldUpdate,
332 '%s has a method called ' +
333 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
@@ -340,7 +340,7 @@ function checkClassInstance(workInProgress: Fiber) {
340 type.prototype.isPureReactComponent &&
341 typeof instance.shouldComponentUpdate !== 'undefined'
342 ) {
343 - warning(
343 + warningWithoutStack(
344 false,
345 '%s has a method called shouldComponentUpdate(). ' +
346 'shouldComponentUpdate should not be used when extending React.PureComponent. ' +
@@ -350,7 +350,7 @@ function checkClassInstance(workInProgress: Fiber) {
350 }
351 const noComponentDidUnmount =
352 typeof instance.componentDidUnmount !== 'function';
353 - warning(
353 + warningWithoutStack(
354 noComponentDidUnmount,
355 '%s has a method called ' +
356 'componentDidUnmount(). But there is no such lifecycle method. ' +
@@ -359,7 +359,7 @@ function checkClassInstance(workInProgress: Fiber) {
359 );
360 const noComponentDidReceiveProps =
361 typeof instance.componentDidReceiveProps !== 'function';
362 - warning(
362 + warningWithoutStack(
363 noComponentDidReceiveProps,
364 '%s has a method called ' +
365 'componentDidReceiveProps(). But there is no such lifecycle method. ' +
@@ -370,7 +370,7 @@ function checkClassInstance(workInProgress: Fiber) {
370 );
371 const noComponentWillRecieveProps =
372 typeof instance.componentWillRecieveProps !== 'function';
373 - warning(
373 + warningWithoutStack(
374 noComponentWillRecieveProps,
375 '%s has a method called ' +
376 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
@@ -378,14 +378,14 @@ function checkClassInstance(workInProgress: Fiber) {
378 );
379 const noUnsafeComponentWillRecieveProps =
380 typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
381 - warning(
381 + warningWithoutStack(
382 noUnsafeComponentWillRecieveProps,
383 '%s has a method called ' +
384 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?',
385 name,
386 );
387 const hasMutatedProps = instance.props !== workInProgress.pendingProps;
388 - warning(
388 + warningWithoutStack(
389 instance.props === undefined || !hasMutatedProps,
390 '%s(...): When calling super() in `%s`, make sure to pass ' +
391 "up the same props that your component's constructor was passed.",
@@ -393,7 +393,7 @@ function checkClassInstance(workInProgress: Fiber) {
393 name,
394 );
395 const noInstanceDefaultProps = !instance.defaultProps;
396 - warning(
396 + warningWithoutStack(
397 noInstanceDefaultProps,
398 'Setting defaultProps as an instance property on %s is not supported and will be ignored.' +
399 ' Instead, define defaultProps as a static property on %s.',
@@ -407,7 +407,7 @@ function checkClassInstance(workInProgress: Fiber) {
407 !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(type)
408 ) {
409 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(type);
410 - warning(
410 + warningWithoutStack(
411 false,
412 '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' +
413 'This component defines getSnapshotBeforeUpdate() only.',
@@ -417,7 +417,7 @@ function checkClassInstance(workInProgress: Fiber) {
417
418 const noInstanceGetDerivedStateFromProps =
419 typeof instance.getDerivedStateFromProps !== 'function';
420 - warning(
420 + warningWithoutStack(
421 noInstanceGetDerivedStateFromProps,
422 '%s: getDerivedStateFromProps() is defined as an instance method ' +
423 'and will be ignored. Instead, declare it as a static method.',
@@ -425,7 +425,7 @@ function checkClassInstance(workInProgress: Fiber) {
425 );
426 const noInstanceGetDerivedStateFromCatch =
427 typeof instance.getDerivedStateFromCatch !== 'function';
428 - warning(
428 + warningWithoutStack(
429 noInstanceGetDerivedStateFromCatch,
430 '%s: getDerivedStateFromCatch() is defined as an instance method ' +
431 'and will be ignored. Instead, declare it as a static method.',
@@ -433,7 +433,7 @@ function checkClassInstance(workInProgress: Fiber) {
433 );
434 const noStaticGetSnapshotBeforeUpdate =
435 typeof type.getSnapshotBeforeUpdate !== 'function';
436 - warning(
436 + warningWithoutStack(
437 noStaticGetSnapshotBeforeUpdate,
438 '%s: getSnapshotBeforeUpdate() is defined as a static method ' +
439 'and will be ignored. Instead, declare it as an instance method.',
@@ -441,10 +441,14 @@ function checkClassInstance(workInProgress: Fiber) {
441 );
442 const state = instance.state;
443 if (state && (typeof state !== 'object' || isArray(state))) {
444 - warning(false, '%s.state: must be set to an object or null', name);
444 + warningWithoutStack(
445 + false,
446 + '%s.state: must be set to an object or null',
447 + name,
448 + );
449 }
450 if (typeof instance.getChildContext === 'function') {
447 - warning(
451 + warningWithoutStack(
452 typeof type.childContextTypes === 'object',
453 '%s.getChildContext(): childContextTypes must be defined in order to ' +
454 'use getChildContext().',
@@ -499,7 +503,7 @@ function constructClassInstance(
503 const componentName = getComponentName(ctor) || 'Component';
504 if (!didWarnAboutUninitializedState.has(componentName)) {
505 didWarnAboutUninitializedState.add(componentName);
502 - warning(
506 + warningWithoutStack(
507 false,
508 '%s: Did not properly initialize state during construction. ' +
509 'Expected state to be an object, but it was %s.',
@@ -557,7 +561,7 @@ function constructClassInstance(
561 : 'getSnapshotBeforeUpdate()';
562 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(componentName)) {
563 didWarnAboutLegacyLifecyclesAndDerivedState.add(componentName);
560 - warning(
564 + warningWithoutStack(
565 false,
566 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
567 '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' +
@@ -600,7 +604,7 @@ function callComponentWillMount(workInProgress, instance) {
604
605 if (oldState !== instance.state) {
606 if (__DEV__) {
603 - warning(
607 + warningWithoutStack(
608 false,
609 '%s.componentWillMount(): Assigning directly to this.state is ' +
610 "deprecated (except inside a component's " +
@@ -634,7 +638,7 @@ function callComponentWillReceiveProps(
638 getComponentName(workInProgress.type) || 'Component';
639 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
640 didWarnAboutStateAssignmentForComponent.add(componentName);
637 - warning(
641 + warningWithoutStack(
642 false,
643 '%s.componentWillReceiveProps(): Assigning directly to ' +
644 "this.state is deprecated (except inside a component's " +
packages/react-reconciler/src/ReactFiberCommitWork.js
+3 -3
@@ -39,7 +39,7 @@ import {
39 } from 'shared/ReactTypeOfSideEffect';
40 import getComponentName from 'shared/getComponentName';
41 import invariant from 'shared/invariant';
42 -import warning from 'shared/warning';
42 +import warningWithoutStack from 'shared/warningWithoutStack';
43
44 import {Sync} from './ReactFiberExpirationTime';
45 import {onCommitUnmount} from './ReactFiberDevToolsHook';
@@ -199,7 +199,7 @@ function commitBeforeMutationLifeCycles(
199 >);
200 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
201 didWarnSet.add(finishedWork.type);
202 - warning(
202 + warningWithoutStack(
203 false,
204 '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' +
205 'must be returned. You have returned undefined.',
@@ -368,7 +368,7 @@ function commitAttachRef(finishedWork: Fiber) {
368 } else {
369 if (__DEV__) {
370 if (!ref.hasOwnProperty('current')) {
371 - warning(
371 + warningWithoutStack(
372 false,
373 'Unexpected ref object provided for %s. ' +
374 'Use either a ref-setter function or React.createRef().%s',
packages/react-reconciler/src/ReactFiberContext.js
+2 -2
@@ -14,7 +14,7 @@ import {isFiberMounted} from 'react-reconciler/reflection';
14 import {ClassComponent, HostRoot} from 'shared/ReactTypeOfWork';
15 import getComponentName from 'shared/getComponentName';
16 import invariant from 'shared/invariant';
17 -import warning from 'shared/warning';
17 +import warningWithoutStack from 'shared/warningWithoutStack';
18 import checkPropTypes from 'prop-types/checkPropTypes';
19
20 import * as ReactCurrentFiber from './ReactCurrentFiber';
@@ -163,7 +163,7 @@ function processChildContext(fiber: Fiber, parentContext: Object): Object {
163
164 if (!warnedAboutMissingGetChildContext[componentName]) {
165 warnedAboutMissingGetChildContext[componentName] = true;
166 - warning(
166 + warningWithoutStack(
167 false,
168 '%s.childContextTypes is specified but there is no getChildContext() method ' +
169 'on the instance. You can either define getChildContext() on %s or remove ' +
packages/react-reconciler/src/ReactFiberDevToolsHook.js
+12 -4
@@ -10,7 +10,7 @@
10 import type {Fiber} from './ReactFiber';
11 import type {FiberRoot} from './ReactFiberRoot';
12
13 -import warning from 'shared/warning';
13 +import warningWithoutStack from 'shared/warningWithoutStack';
14
15 declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: Object | void;
16
@@ -25,7 +25,11 @@ function catchErrors(fn) {
25 } catch (err) {
26 if (__DEV__ && !hasLoggedError) {
27 hasLoggedError = true;
28 - warning(false, 'React DevTools encountered an error: %s', err);
28 + warningWithoutStack(
29 + false,
30 + 'React DevTools encountered an error: %s',
31 + err,
32 + );
33 }
34 }
35 };
@@ -48,7 +52,7 @@ export function injectInternals(internals: Object): boolean {
52 }
53 if (!hook.supportsFiber) {
54 if (__DEV__) {
51 - warning(
55 + warningWithoutStack(
56 false,
57 'The installed version of React DevTools is too old and will not work ' +
58 'with the current version of React. Please update React DevTools. ' +
@@ -70,7 +74,11 @@ export function injectInternals(internals: Object): boolean {
74 } catch (err) {
75 // Catch all errors because it is unsafe to throw during initialization.
76 if (__DEV__) {
73 - warning(false, 'React DevTools encountered an error: %s.', err);
77 + warningWithoutStack(
78 + false,
79 + 'React DevTools encountered an error: %s.',
80 + err,
81 + );
82 }
83 }
84 // DevTools exists
packages/react-reconciler/src/ReactFiberNewContext.js
+3 -3
@@ -18,7 +18,7 @@ export type NewContext = {
18 getContextChangedBits(context: ReactContext<any>): number,
19 };
20
21 -import warning from 'shared/warning';
21 +import warningWithoutStack from 'shared/warningWithoutStack';
22 import {isPrimaryRenderer} from './ReactFiberHostConfig';
23 import {createCursor, push, pop} from './ReactFiberStack';
24
@@ -43,7 +43,7 @@ function pushProvider(providerFiber: Fiber): void {
43 context._currentValue = providerFiber.pendingProps.value;
44 context._changedBits = providerFiber.stateNode;
45 if (__DEV__) {
46 - warning(
46 + warningWithoutStack(
47 context._currentRenderer === undefined ||
48 context._currentRenderer === null ||
49 context._currentRenderer === rendererSigil,
@@ -60,7 +60,7 @@ function pushProvider(providerFiber: Fiber): void {
60 context._currentValue2 = providerFiber.pendingProps.value;
61 context._changedBits2 = providerFiber.stateNode;
62 if (__DEV__) {
63 - warning(
63 + warningWithoutStack(
64 context._currentRenderer2 === undefined ||
65 context._currentRenderer2 === null ||
66 context._currentRenderer2 === rendererSigil,
packages/react-reconciler/src/ReactFiberReconciler.js
+3 -3
@@ -26,7 +26,7 @@ import * as ReactInstanceMap from 'shared/ReactInstanceMap';
26 import {HostComponent} from 'shared/ReactTypeOfWork';
27 import getComponentName from 'shared/getComponentName';
28 import invariant from 'shared/invariant';
29 -import warning from 'shared/warning';
29 +import warningWithoutStack from 'shared/warningWithoutStack';
30
31 import {getPublicInstance} from './ReactFiberHostConfig';
32 import {
@@ -109,7 +109,7 @@ function scheduleRootUpdate(
109 !didWarnAboutNestedUpdates
110 ) {
111 didWarnAboutNestedUpdates = true;
112 - warning(
112 + warningWithoutStack(
113 false,
114 'Render methods should be a pure function of props and state; ' +
115 'triggering nested component updates from render is not allowed. ' +
@@ -127,7 +127,7 @@ function scheduleRootUpdate(
127
128 callback = callback === undefined ? null : callback;
129 if (callback !== null) {
130 - warning(
130 + warningWithoutStack(
131 typeof callback === 'function',
132 'render(...): Expected the last optional `callback` argument to be a ' +
133 'function. Instead received: %s.',
packages/react-reconciler/src/ReactFiberScheduler.js
+5 -5
@@ -46,7 +46,7 @@ import {
46 } from 'shared/ReactFeatureFlags';
47 import getComponentName from 'shared/getComponentName';
48 import invariant from 'shared/invariant';
49 -import warning from 'shared/warning';
49 +import warningWithoutStack from 'shared/warningWithoutStack';
50
51 import {
52 scheduleTimeout,
@@ -179,7 +179,7 @@ if (__DEV__) {
179 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
180 return;
181 }
182 - warning(
182 + warningWithoutStack(
183 false,
184 "Can't call setState (or forceUpdate) on an unmounted component. This " +
185 'is a no-op, but it indicates a memory leak in your application. To ' +
@@ -196,7 +196,7 @@ if (__DEV__) {
196 if (didWarnSetStateChildContext) {
197 return;
198 }
199 - warning(
199 + warningWithoutStack(
200 false,
201 'setState(...): Cannot call setState() inside getChildContext()',
202 );
@@ -206,7 +206,7 @@ if (__DEV__) {
206 if (didWarnAboutStateTransition) {
207 return;
208 }
209 - warning(
209 + warningWithoutStack(
210 false,
211 'Cannot update during an existing state transition (such as within ' +
212 "`render` or another component's constructor). Render methods should " +
@@ -275,7 +275,7 @@ if (__DEV__ && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
275 // Restore the original state of the work-in-progress
276 if (stashedWorkInProgressProperties === null) {
277 // This should never happen. Don't throw because this code is DEV-only.
278 - warning(
278 + warningWithoutStack(
279 false,
280 'Could not replay rendering after an error. This is likely a bug in React. ' +
281 'Please file an issue.',
packages/react-reconciler/src/ReactFiberStack.js
+4 -4
@@ -9,7 +9,7 @@
9
10 import type {Fiber} from './ReactFiber';
11
12 -import warning from 'shared/warning';
12 +import warningWithoutStack from 'shared/warningWithoutStack';
13
14 export type StackCursor<T> = {
15 current: T,
@@ -38,14 +38,14 @@ function isEmpty(): boolean {
38 function pop<T>(cursor: StackCursor<T>, fiber: Fiber): void {
39 if (index < 0) {
40 if (__DEV__) {
41 - warning(false, 'Unexpected pop.');
41 + warningWithoutStack(false, 'Unexpected pop.');
42 }
43 return;
44 }
45
46 if (__DEV__) {
47 if (fiber !== fiberStack[index]) {
48 - warning(false, 'Unexpected Fiber popped.');
48 + warningWithoutStack(false, 'Unexpected Fiber popped.');
49 }
50 }
51
@@ -75,7 +75,7 @@ function push<T>(cursor: StackCursor<T>, value: T, fiber: Fiber): void {
75 function checkThatStackIsEmpty() {
76 if (__DEV__) {
77 if (index !== -1) {
78 - warning(
78 + warningWithoutStack(
79 false,
80 'Expected an empty stack. Something was not reset properly.',
81 );
packages/react-reconciler/src/ReactFiberTreeReflection.js
+2 -2
@@ -10,7 +10,7 @@
10 import type {Fiber} from 'react-reconciler/src/ReactFiber';
11
12 import invariant from 'shared/invariant';
13 -import warning from 'shared/warning';
13 +import warningWithoutStack from 'shared/warningWithoutStack';
14
15 import * as ReactInstanceMap from 'shared/ReactInstanceMap';
16 import ReactSharedInternals from 'shared/ReactSharedInternals';
@@ -69,7 +69,7 @@ export function isMounted(component: React$Component<any, any>): boolean {
69 if (owner !== null && owner.tag === ClassComponent) {
70 const ownerFiber: Fiber = owner;
71 const instance = ownerFiber.stateNode;
72 - warning(
72 + warningWithoutStack(
73 instance._warnedAboutRefsInRender,
74 '%s is accessing isMounted inside its render() function. ' +
75 'render() should be a pure function of props and state. It should ' +
packages/react-reconciler/src/ReactProfilerTimer.js
+4 -4
@@ -12,7 +12,7 @@ import type {Fiber} from './ReactFiber';
12 import getComponentName from 'shared/getComponentName';
13 import {enableProfilerTimer} from 'shared/ReactFeatureFlags';
14
15 -import warning from 'shared/warning';
15 +import warningWithoutStack from 'shared/warningWithoutStack';
16 import {now} from './ReactFiberHostConfig';
17
18 export type ProfilerTimer = {
@@ -64,7 +64,7 @@ function checkActualRenderTimeStackEmpty(): void {
64 return;
65 }
66 if (__DEV__) {
67 - warning(
67 + warningWithoutStack(
68 fiberStack.length === 0,
69 'Expected an empty stack. Something was not reset properly.',
70 );
@@ -106,7 +106,7 @@ function recordElapsedActualRenderTime(fiber: Fiber): void {
106 return;
107 }
108 if (__DEV__) {
109 - warning(
109 + warningWithoutStack(
110 fiber === fiberStack.pop(),
111 'Unexpected Fiber (%s) popped.',
112 getComponentName(fiber.type),
@@ -163,7 +163,7 @@ function startBaseRenderTimer(): void {
163 }
164 if (__DEV__) {
165 if (baseStartTime !== -1) {
166 - warning(
166 + warningWithoutStack(
167 false,
168 'Cannot start base timer that is already running. ' +
169 'This error is likely caused by a bug in React. ' +
packages/react-reconciler/src/ReactStrictModeWarnings.js
+5 -5
@@ -14,7 +14,7 @@ import {getStackByFiberInDevAndProd} from './ReactCurrentFiber';
14 import getComponentName from 'shared/getComponentName';
15 import {StrictMode} from './ReactTypeOfMode';
16 import lowPriorityWarning from 'shared/lowPriorityWarning';
17 -import warning from 'shared/warning';
17 +import warningWithoutStack from 'shared/warningWithoutStack';
18
19 type LIFECYCLE =
20 | 'UNSAFE_componentWillMount'
@@ -99,7 +99,7 @@ if (__DEV__) {
99 strictRoot,
100 );
101
102 - warning(
102 + warningWithoutStack(
103 false,
104 'Unsafe lifecycle methods were found within a strict-mode tree:%s' +
105 '\n\n%s' +
@@ -235,7 +235,7 @@ if (__DEV__) {
235 ) => {
236 const strictRoot = findStrictRoot(fiber);
237 if (strictRoot === null) {
238 - warning(
238 + warningWithoutStack(
239 false,
240 'Expected to find a StrictMode component in a strict mode tree. ' +
241 'This error is likely caused by a bug in React. Please file an issue.',
@@ -304,7 +304,7 @@ if (__DEV__) {
304 ) => {
305 const strictRoot = findStrictRoot(fiber);
306 if (strictRoot === null) {
307 - warning(
307 + warningWithoutStack(
308 false,
309 'Expected to find a StrictMode component in a strict mode tree. ' +
310 'This error is likely caused by a bug in React. Please file an issue.',
@@ -346,7 +346,7 @@ if (__DEV__) {
346 strictRoot,
347 );
348
349 - warning(
349 + warningWithoutStack(
350 false,
351 'Legacy context API has been detected within a strict-mode tree: %s' +
352 '\n\nPlease update the following components: %s' +
packages/react-reconciler/src/ReactUpdateQueue.js
+2 -2
@@ -103,7 +103,7 @@ import {
103 import {StrictMode} from './ReactTypeOfMode';
104
105 import invariant from 'shared/invariant';
106 -import warning from 'shared/warning';
106 +import warningWithoutStack from 'shared/warningWithoutStack';
107
108 export type Update<State> = {
109 expirationTime: ExpirationTime,
@@ -296,7 +296,7 @@ export function enqueueUpdate<State>(
296 (queue2 !== null && currentlyProcessingQueue === queue2)) &&
297 !didWarnUpdateInsideUpdate
298 ) {
299 - warning(
299 + warningWithoutStack(
300 false,
301 'An update (setState, replaceState, or forceUpdate) was scheduled ' +
302 'from inside an update function. Update functions should be pure, ' +
packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js
+5 -12
@@ -701,8 +701,6 @@ describe('ReactNewContext', () => {
701 });
702
703 it('warns if calculateChangedBits returns larger than a 31-bit integer', () => {
704 - spyOnDev(console, 'error');
705 -
704 const Context = React.createContext(
705 0,
706 (a, b) => Math.pow(2, 32) - 1, // Return 32 bit int
@@ -713,16 +711,11 @@ describe('ReactNewContext', () => {
711
712 // Update
713 ReactNoop.render(<Context.Provider value={2} />);
716 - ReactNoop.flush();
717 -
718 - if (__DEV__) {
719 - expect(console.error).toHaveBeenCalledTimes(1);
720 - expect(console.error.calls.argsFor(0)[0]).toContain(
721 - 'calculateChangedBits: Expected the return value to be a 31-bit ' +
722 - 'integer. Instead received: 4294967295',
723 - {withoutStack: true}, // TODO: add a stack
724 - );
725 - }
714 + expect(ReactNoop.flush).toWarnDev(
715 + 'calculateChangedBits: Expected the return value to be a 31-bit ' +
716 + 'integer. Instead received: 4294967295',
717 + {withoutStack: true}, // TODO: add a stack
718 + );
719 });
720
721 it('warns if multiple renderers concurrently render the same context', () => {
packages/react-scheduler/src/ReactScheduler.js
+3 -3
@@ -42,7 +42,7 @@ type CallbackConfigType = {|
42 export type CallbackIdType = CallbackConfigType;
43
44 import {canUseDOM} from 'shared/ExecutionEnvironment';
45 -import warning from 'shared/warning';
45 +import warningWithoutStack from 'shared/warningWithoutStack';
46
47 // We capture a local reference to any global, in case it gets polyfilled after
48 // this module is initially evaluated.
@@ -124,7 +124,7 @@ if (!canUseDOM) {
124 };
125 } else {
126 if (typeof localRequestAnimationFrame !== 'function') {
127 - warning(
127 + warningWithoutStack(
128 false,
129 "This browser doesn't support requestAnimationFrame. " +
130 'Make sure that you load a ' +
@@ -132,7 +132,7 @@ if (!canUseDOM) {
132 );
133 }
134 if (typeof localCancelAnimationFrame !== 'function') {
135 - warning(
135 + warningWithoutStack(
136 false,
137 "This browser doesn't support cancelAnimationFrame. " +
138 'Make sure that you load a ' +
packages/react/src/ReactChildren.js
+1 -2
@@ -166,8 +166,7 @@ function traverseAllChildrenImpl(
166 didWarnAboutMaps,
167 'Using Maps as children is unsupported and will likely yield ' +
168 'unexpected results. Convert it to a sequence/iterable of keyed ' +
169 - 'ReactElements instead.%s',
170 - ReactDebugCurrentFrame.getStackAddendum(),
169 + 'ReactElements instead.',
170 );
171 didWarnAboutMaps = true;
172 }
packages/react/src/ReactContext.js
+2 -2
@@ -11,7 +11,7 @@ import {REACT_PROVIDER_TYPE, REACT_CONTEXT_TYPE} from 'shared/ReactSymbols';
11
12 import type {ReactContext} from 'shared/ReactTypes';
13
14 -import warning from 'shared/warning';
14 +import warningWithoutStack from 'shared/warningWithoutStack';
15
16 export function createContext<T>(
17 defaultValue: T,
@@ -21,7 +21,7 @@ export function createContext<T>(
21 calculateChangedBits = null;
22 } else {
23 if (__DEV__) {
24 - warning(
24 + warningWithoutStack(
25 calculateChangedBits === null ||
26 typeof calculateChangedBits === 'function',
27 'createContext: Expected the optional second argument to be a ' +
packages/react/src/ReactElement.js
+3 -3
@@ -6,7 +6,7 @@
6 */
7
8 import invariant from 'shared/invariant';
9 -import warning from 'shared/warning';
9 +import warningWithoutStack from 'shared/warningWithoutStack';
10 import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';
11
12 import ReactCurrentOwner from './ReactCurrentOwner';
@@ -50,7 +50,7 @@ function defineKeyPropWarningGetter(props, displayName) {
50 const warnAboutAccessingKey = function() {
51 if (!specialPropKeyWarningShown) {
52 specialPropKeyWarningShown = true;
53 - warning(
53 + warningWithoutStack(
54 false,
55 '%s: `key` is not a prop. Trying to access it will result ' +
56 'in `undefined` being returned. If you need to access the same ' +
@@ -71,7 +71,7 @@ function defineRefPropWarningGetter(props, displayName) {
71 const warnAboutAccessingRef = function() {
72 if (!specialPropRefWarningShown) {
73 specialPropRefWarningShown = true;
74 - warning(
74 + warningWithoutStack(
75 false,
76 '%s: `ref` is not a prop. Trying to access it will result ' +
77 'in `undefined` being returned. If you need to access the same ' +
packages/react/src/ReactElementValidator.js
+6 -13
@@ -22,6 +22,7 @@ import {
22 } from 'shared/ReactSymbols';
23 import checkPropTypes from 'prop-types/checkPropTypes';
24 import warning from 'shared/warning';
25 +import warningWithoutStack from 'shared/warningWithoutStack';
26
27 import ReactCurrentOwner from './ReactCurrentOwner';
28 import {isValidElement, createElement, cloneElement} from './ReactElement';
@@ -124,10 +125,9 @@ function validateExplicitKey(element, parentType) {
125 warning(
126 false,
127 'Each child in an array or iterator should have a unique "key" prop.' +
127 - '%s%s See https://fb.me/react-warning-keys for more information.%s',
128 + '%s%s See https://fb.me/react-warning-keys for more information.',
129 currentComponentErrorInfo,
130 childOwner,
130 - ReactDebugCurrentFrame.getStackAddendum(),
131 );
132 }
133 setCurrentlyValidatingElement(null);
@@ -213,14 +213,14 @@ function validatePropTypes(element) {
213 setCurrentlyValidatingElement(null);
214 } else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) {
215 propTypesMisspellWarningShown = true;
216 - warning(
216 + warningWithoutStack(
217 false,
218 'Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?',
219 name || 'Unknown',
220 );
221 }
222 if (typeof type.getDefaultProps === 'function') {
223 - warning(
223 + warningWithoutStack(
224 type.getDefaultProps.isReactClassApproved,
225 'getDefaultProps is only used on classic React.createClass ' +
226 'definitions. Use a static property named `defaultProps` instead.',
@@ -242,20 +242,15 @@ function validateFragmentProps(fragment) {
242 warning(
243 false,
244 'Invalid prop `%s` supplied to `React.Fragment`. ' +
245 - 'React.Fragment can only have `key` and `children` props.%s',
245 + 'React.Fragment can only have `key` and `children` props.',
246 key,
247 - ReactDebugCurrentFrame.getStackAddendum(),
247 );
248 break;
249 }
250 }
251
252 if (fragment.ref !== null) {
254 - warning(
255 - false,
256 - 'Invalid attribute `ref` supplied to `React.Fragment`.%s',
257 - ReactDebugCurrentFrame.getStackAddendum(),
258 - );
253 + warning(false, 'Invalid attribute `ref` supplied to `React.Fragment`.');
254 }
255
256 setCurrentlyValidatingElement(null);
@@ -286,8 +281,6 @@ export function createElementWithValidation(type, props, children) {
281 info += getDeclarationErrorAddendum();
282 }
283
289 - info += ReactDebugCurrentFrame.getStackAddendum();
290 -
284 let typeString;
285 if (type === null) {
286 typeString = 'null';
packages/react/src/ReactNoopUpdateQueue.js
+2 -2
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import warning from 'shared/warning';
8 +import warningWithoutStack from 'shared/warningWithoutStack';
9
10 const didWarnStateUpdateForUnmountedComponent = {};
11
@@ -19,7 +19,7 @@ function warnNoop(publicInstance, callerName) {
19 if (didWarnStateUpdateForUnmountedComponent[warningKey]) {
20 return;
21 }
22 - warning(
22 + warningWithoutStack(
23 false,
24 "Can't call %s on a component that is not yet mounted. " +
25 'This is a no-op, but it might indicate a bug in your application. ' +
packages/react/src/forwardRef.js
+4 -4
@@ -7,20 +7,20 @@
7
8 import {REACT_FORWARD_REF_TYPE} from 'shared/ReactSymbols';
9
10 -import warning from 'shared/warning';
10 +import warningWithoutStack from 'shared/warningWithoutStack';
11
12 export default function forwardRef<Props, ElementType: React$ElementType>(
13 render: (props: Props, ref: React$Ref<ElementType>) => React$Node,
14 ) {
15 if (__DEV__) {
16 if (typeof render !== 'function') {
17 - warning(
17 + warningWithoutStack(
18 false,
19 'forwardRef requires a render function but was given %s.',
20 render === null ? 'null' : typeof render,
21 );
22 } else {
23 - warning(
23 + warningWithoutStack(
24 render.length === 2,
25 'forwardRef render functions accept two parameters: props and ref. ' +
26 'Did you forget to use the ref parameter?',
@@ -28,7 +28,7 @@ export default function forwardRef<Props, ElementType: React$ElementType>(
28 }
29
30 if (render != null) {
31 - warning(
31 + warningWithoutStack(
32 render.defaultProps == null && render.propTypes == null,
33 'forwardRef render functions do not support propTypes or defaultProps. ' +
34 'Did you accidentally pass a React component?',
packages/shared/getComponentName.js
+2 -2
@@ -7,7 +7,7 @@
7 * @flow
8 */
9
10 -import warning from 'shared/warning';
10 +import warningWithoutStack from 'shared/warningWithoutStack';
11 import {
12 REACT_ASYNC_MODE_TYPE,
13 REACT_CONTEXT_TYPE,
@@ -27,7 +27,7 @@ function getComponentName(type: mixed): string | null {
27 }
28 if (__DEV__) {
29 if (typeof (type: any).tag === 'number') {
30 - warning(
30 + warningWithoutStack(
31 false,
32 'Received an unexpected object in getComponentName(). ' +
33 'This is likely a bug in React. Please file an issue.',
packages/shared/lowPriorityWarning.js
+1 -1
@@ -39,7 +39,7 @@ if (__DEV__) {
39 lowPriorityWarning = function(condition, format, ...args) {
40 if (format === undefined) {
41 throw new Error(
42 - '`warning(condition, format, ...args)` requires a warning ' +
42 + '`warningWithoutStack(condition, format, ...args)` requires a warning ' +
43 'message argument',
44 );
45 }
packages/shared/warning.js
+10 -23
@@ -5,6 +5,9 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 +import warningWithoutStack from 'shared/warningWithoutStack';
9 +import ReactSharedInternals from 'shared/ReactSharedInternals';
10 +
11 /**
12 * Similar to invariant but only logs a warning if the condition is not met.
13 * This can be used to log issues in development environments in critical
@@ -12,33 +15,17 @@
15 * same logic and follow the same code paths.
16 */
17
15 -let warning = () => {};
18 +let warning = warningWithoutStack;
19
20 if (__DEV__) {
18 - const printWarning = function(format, ...args) {
19 - let argIndex = 0;
20 - const message = 'Warning: ' + format.replace(/%s/g, () => args[argIndex++]);
21 - if (typeof console !== 'undefined') {
22 - console.error(message);
23 - }
24 - try {
25 - // --- Welcome to debugging React ---
26 - // This error was thrown as a convenience so that you can use this stack
27 - // to find the callsite that caused this warning to fire.
28 - throw new Error(message);
29 - } catch (x) {}
30 - };
31 -
21 warning = function(condition, format, ...args) {
33 - if (format === undefined) {
34 - throw new Error(
35 - '`warning(condition, format, ...args)` requires a warning ' +
36 - 'message argument',
37 - );
38 - }
39 - if (!condition) {
40 - printWarning(format, ...args);
22 + if (condition) {
23 + return;
24 }
25 + const ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
26 + const stack = ReactDebugCurrentFrame.getStackAddendum();
27 + // eslint-disable-next-line react-internal/warning-and-invariant-args
28 + warningWithoutStack(false, format + '%s', ...args, stack);
29 };
30 }
31
packages/shared/warningWithoutStack.js new
+43
@@ -0,0 +1,43 @@
1 +/**
2 + * Copyright (c) 2013-present, Facebook, Inc.
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 +
8 +/**
9 + * Similar to invariant but only logs a warning if the condition is not met.
10 + * This can be used to log issues in development environments in critical
11 + * paths. Removing the logging code for production environments will keep the
12 + * same logic and follow the same code paths.
13 + */
14 +
15 +let warningWithoutStack = () => {};
16 +
17 +if (__DEV__) {
18 + warningWithoutStack = function(condition, format, ...args) {
19 + if (format === undefined) {
20 + throw new Error(
21 + '`warningWithoutStack(condition, format, ...args)` requires a warning ' +
22 + 'message argument',
23 + );
24 + }
25 + if (condition) {
26 + return;
27 + }
28 + if (typeof console !== 'undefined') {
29 + console.error('Warning: ' + format, ...args);
30 + }
31 + try {
32 + // --- Welcome to debugging React ---
33 + // This error was thrown as a convenience so that you can use this stack
34 + // to find the callsite that caused this warning to fire.
35 + let argIndex = 0;
36 + const message =
37 + 'Warning: ' + format.replace(/%s/g, () => args[argIndex++]);
38 + throw new Error(message);
39 + } catch (x) {}
40 + };
41 +}
42 +
43 +export default warningWithoutStack;
packages/simple-cache-provider/src/SimpleCacheProvider.js
+5 -5
@@ -8,7 +8,7 @@
8 */
9
10 import React from 'react';
11 -import warning from 'shared/warning';
11 +import warningWithoutStack from 'shared/warningWithoutStack';
12
13 function noop() {}
14
@@ -154,7 +154,7 @@ export function createCache(invalidator: () => mixed): Cache {
154
155 function accessRecord<K, V>(resourceType: any, key: K): Record<K, V> {
156 if (__DEV__) {
157 - warning(
157 + warningWithoutStack(
158 typeof resourceType !== 'string' && typeof resourceType !== 'number',
159 'Invalid resourceType: Expected a symbol, object, or function, but ' +
160 'instead received: %s. Strings and numbers are not permitted as ' +
@@ -314,7 +314,7 @@ export function createCache(invalidator: () => mixed): Cache {
314 let warnIfNonPrimitiveKey;
315 if (__DEV__) {
316 warnIfNonPrimitiveKey = (key, methodName) => {
317 - warning(
317 + warningWithoutStack(
318 typeof key === 'string' ||
319 typeof key === 'number' ||
320 typeof key === 'boolean' ||
@@ -361,7 +361,7 @@ export function createResource<V, K, H: primitive>(
361 const resource = {
362 read(cache, key) {
363 if (__DEV__) {
364 - warning(
364 + warningWithoutStack(
365 isCache(cache),
366 'read(): The first argument must be a cache. Instead received: %s',
367 cache,
@@ -378,7 +378,7 @@ export function createResource<V, K, H: primitive>(
378 },
379 preload(cache, key) {
380 if (__DEV__) {
381 - warning(
381 + warningWithoutStack(
382 isCache(cache),
383 'preload(): The first argument must be a cache. Instead received: %s',
384 cache,
scripts/babel/__tests__/wrap-warning-with-env-check-test.js
+7
@@ -40,6 +40,13 @@ describe('wrap-warning-with-env-check', () => {
40 );
41 });
42
43 + it('should wrap warningWithoutStack calls', () => {
44 + compare(
45 + "warningWithoutStack(condition, 'a %s b', 'c');",
46 + "__DEV__ ? !condition ? warningWithoutStack(false, 'a %s b', 'c') : void 0 : void 0;"
47 + );
48 + });
49 +
50 it('should not wrap invariant calls', () => {
51 compare(
52 "invariant(condition, 'a %s b', 'c');",
scripts/babel/wrap-warning-with-env-check.js
+4 -1
@@ -24,7 +24,10 @@ module.exports = function(babel, options) {
24 return;
25 }
26
27 - if (path.get('callee').isIdentifier({name: 'warning'})) {
27 + if (
28 + path.get('callee').isIdentifier({name: 'warning'}) ||
29 + path.get('callee').isIdentifier({name: 'warningWithoutStack'})
30 + ) {
31 // Turns this code:
32 //
33 // warning(condition, argument, argument);
scripts/eslint-rules/warning-and-invariant-args.js
+3 -1
@@ -35,7 +35,9 @@ module.exports = function(context) {
35 // how warning/invariant was defined.
36 const isWarningOrInvariant =
37 node.callee.type === 'Identifier' &&
38 - (node.callee.name === 'warning' || node.callee.name === 'invariant');
38 + (node.callee.name === 'warning' ||
39 + node.callee.name === 'warningWithoutStack' ||
40 + node.callee.name === 'invariant');
41 if (!isWarningOrInvariant) {
42 return;
43 }
scripts/jest/matchers/__tests__/toWarnDev-test.js
+14
@@ -147,5 +147,19 @@ describe('toWarnDev', () => {
147 }).toWarnDev('Hi', {withoutStack: 'haha'});
148 }).toThrow('Instead received string');
149 });
150 +
151 + it('fails if the argument number does not match', () => {
152 + expect(() => {
153 + expect(() => {
154 + console.error('Hi %s', 'Sara', 'extra');
155 + }).toWarnDev('Hi', {withoutStack: true});
156 + }).toThrow('Received 2 arguments for a message with 1 placeholders');
157 +
158 + expect(() => {
159 + expect(() => {
160 + console.error('Hi %s');
161 + }).toWarnDev('Hi', {withoutStack: true});
162 + }).toThrow('Received 0 arguments for a message with 1 placeholders');
163 + });
164 }
165 });
scripts/jest/matchers/toWarnDev.js
+32 -1
@@ -1,6 +1,7 @@
1 'use strict';
2
3 const jestDiff = require('jest-diff');
4 +const util = require('util');
5
6 function normalizeCodeLocInfo(str) {
7 return str && str.replace(/at .+?:\d+/g, 'at **');
@@ -23,6 +24,7 @@ const createMatcherFor = consoleMethod =>
24 const warningsWithoutComponentStack = [];
25 const warningsWithComponentStack = [];
26 const unexpectedWarnings = [];
27 + let lastWarningWithMismatchingFormat = null;
28
29 // Catch errors thrown by the callback,
30 // But only rethrow them if all test expectations have been satisfied.
@@ -30,9 +32,23 @@ const createMatcherFor = consoleMethod =>
32 // and result in a test that passes when it shouldn't.
33 let caughtError;
34
33 - const consoleSpy = message => {
35 + const consoleSpy = (format, ...args) => {
36 + const message = util.format(format, ...args);
37 const normalizedMessage = normalizeCodeLocInfo(message);
38
39 + // Remember if the number of %s interpolations
40 + // doesn't match the number of arguments.
41 + // We'll fail the test if it happens.
42 + let argIndex = 0;
43 + format.replace(/%s/g, () => argIndex++);
44 + if (argIndex !== args.length) {
45 + lastWarningWithMismatchingFormat = {
46 + format,
47 + args,
48 + expectedArgCount: argIndex,
49 + };
50 + }
51 +
52 for (let index = 0; index < expectedMessages.length; index++) {
53 const expectedMessage = expectedMessages[index];
54 if (
@@ -160,6 +176,21 @@ const createMatcherFor = consoleMethod =>
176 `Instead received ${typeof withoutStack}.`
177 );
178 }
179 +
180 + if (lastWarningWithMismatchingFormat !== null) {
181 + return {
182 + message: () =>
183 + `Received ${
184 + lastWarningWithMismatchingFormat.args.length
185 + } arguments for a message with ${
186 + lastWarningWithMismatchingFormat.expectedArgCount
187 + } placeholders:\n ${this.utils.printReceived(
188 + lastWarningWithMismatchingFormat.format
189 + )}`,
190 + pass: false,
191 + };
192 + }
193 +
194 return {pass: true};
195 }
196 } else {
scripts/rollup/forks.js
+14 -1
@@ -40,10 +40,23 @@ const forks = Object.freeze({
40
41 // Without this fork, importing `shared/ReactSharedInternals` inside
42 // the `react` package itself would not work due to a cyclical dependency.
43 - 'shared/ReactSharedInternals': (bundleType, entry) => {
43 + 'shared/ReactSharedInternals': (bundleType, entry, dependencies) => {
44 if (entry === 'react') {
45 return 'react/src/ReactSharedInternals';
46 }
47 + if (dependencies.indexOf('react') === -1) {
48 + // React internals are unavailable if we can't reference the package.
49 + // We return an error because we only want to throw if this module gets used.
50 + return new Error(
51 + 'Cannot use a module that depends on ReactSharedInternals ' +
52 + 'from "' +
53 + entry +
54 + '" because it does not declare "react" in the package ' +
55 + 'dependencies or peerDependencies. For example, this can happen if you use ' +
56 + 'warning() instead of warningWithoutStack() in a package that does not ' +
57 + 'depend on React.'
58 + );
59 + }
60 return null;
61 },
62
scripts/rollup/plugins/use-forks-plugin.js
+12 -2
@@ -33,7 +33,13 @@ function useForks(forks) {
33 const targetModule = forks[srcModule];
34 resolvedForks.set(
35 require.resolve(srcModule),
36 - require.resolve(targetModule)
36 + // targetModule could be a string (a file path),
37 + // or an error (which we'd throw if it gets used).
38 + // Don't try to "resolve" errors, but cache
39 + // resolved file paths.
40 + typeof targetModule === 'string'
41 + ? require.resolve(targetModule)
42 + : targetModule
43 );
44 });
45 return {
@@ -64,7 +70,11 @@ function useForks(forks) {
70 }
71 if (resolvedImportee && resolvedForks.has(resolvedImportee)) {
72 // We found a fork!
67 - return resolvedForks.get(resolvedImportee);
73 + const fork = resolvedForks.get(resolvedImportee);
74 + if (fork instanceof Error) {
75 + throw fork;
76 + }
77 + return fork;
78 }
79 return null;
80 },