Add component stack to ReactControlledValuePropTypes (#9435)
Ben Alpert committed
Apr 14, 2017 at 19:50 UTC
7bf686b76f20eca07f0abef1bf6a0f0380b0c3f2
8 files changed
+38
-29
src/renderers/dom/fiber/wrappers/ReactDOMFiberInput.js
+1
-1
@@ -94,7 +94,7 @@ var ReactDOMInput = {
94
ReactControlledValuePropTypes.checkPropTypes(
95
'input',
96
props,
97
- getCurrentFiberOwnerName(),
97
+ getCurrentFiberStackAddendum,
98
);
99
100
if (
src/renderers/dom/fiber/wrappers/ReactDOMFiberSelect.js
+5
-1
@@ -23,6 +23,10 @@ var ReactControlledValuePropTypes = require('ReactControlledValuePropTypes');
23
var {getCurrentFiberOwnerName} = require('ReactDebugCurrentFiber');
24
var warning = require('fbjs/lib/warning');
25
26
+if (__DEV__) {
27
+ var {getCurrentFiberStackAddendum} = require('ReactDebugCurrentFiber');
28
+}
29
+
30
var didWarnValueDefaultValue = false;
31
32
function getDeclarationErrorAddendum() {
@@ -42,7 +46,7 @@ function checkSelectPropTypes(props) {
46
ReactControlledValuePropTypes.checkPropTypes(
47
'select',
48
props,
45
- getCurrentFiberOwnerName(),
49
+ getCurrentFiberStackAddendum,
50
);
51
52
for (var i = 0; i < valuePropNames.length; i++) {
src/renderers/dom/fiber/wrappers/ReactDOMFiberTextarea.js
+5
-2
@@ -19,11 +19,14 @@ type TextAreaWithWrapperState = HTMLTextAreaElement & {
19
};
20
21
var ReactControlledValuePropTypes = require('ReactControlledValuePropTypes');
22
-var {getCurrentFiberOwnerName} = require('ReactDebugCurrentFiber');
22
23
var invariant = require('fbjs/lib/invariant');
24
var warning = require('fbjs/lib/warning');
25
26
+if (__DEV__) {
27
+ var {getCurrentFiberStackAddendum} = require('ReactDebugCurrentFiber');
28
+}
29
+
30
var didWarnValDefaultVal = false;
31
32
/**
@@ -69,7 +72,7 @@ var ReactDOMTextarea = {
72
ReactControlledValuePropTypes.checkPropTypes(
73
'textarea',
74
props,
72
- getCurrentFiberOwnerName(),
75
+ getCurrentFiberStackAddendum,
76
);
77
if (
78
props.value !== undefined &&
src/renderers/dom/shared/utils/ReactControlledValuePropTypes.js
+2
-9
@@ -61,19 +61,13 @@ var propTypes = {
61
};
62
63
var loggedTypeFailures = {};
64
-function getDeclarationErrorAddendum(ownerName) {
65
- if (ownerName) {
66
- return '\n\nCheck the render method of `' + ownerName + '`.';
67
- }
68
- return '';
69
-}
64
65
/**
66
* Provide a linked `value` attribute for controlled forms. You should not use
67
* this outside of the ReactDOM controlled form components.
68
*/
69
var ReactControlledValuePropTypes = {
76
- checkPropTypes: function(tagName, props, ownerName) {
70
+ checkPropTypes: function(tagName, props, getStack) {
71
for (var propName in propTypes) {
72
if (propTypes.hasOwnProperty(propName)) {
73
var error = propTypes[propName](
@@ -90,8 +84,7 @@ var ReactControlledValuePropTypes = {
84
// same error.
85
loggedTypeFailures[error.message] = true;
86
93
- var addendum = getDeclarationErrorAddendum(ownerName);
94
- warning(false, 'Failed form propType: %s%s', error.message, addendum);
87
+ warning(false, 'Failed form propType: %s%s', error.message, getStack());
88
}
89
}
90
},
src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
+7
@@ -642,6 +642,13 @@ describe('ReactDOMInput', () => {
642
<input type="text" value="zoink" readOnly={false} />,
643
);
644
expectDev(console.error.calls.count()).toBe(1);
645
+ expectDev(normalizeCodeLocInfo(console.error.calls.argsFor(0)[0])).toBe(
646
+ 'Warning: Failed form propType: You provided a `value` prop to a form ' +
647
+ 'field without an `onChange` handler. This will render a read-only ' +
648
+ 'field. If the field should be mutable use `defaultValue`. ' +
649
+ 'Otherwise, set either `onChange` or `readOnly`.\n' +
650
+ ' in input (at **)',
651
+ );
652
});
653
654
it('should have a this value of undefined if bind is not used', () => {
src/renderers/dom/stack/client/wrappers/ReactDOMInput.js
+2
-5
@@ -83,11 +83,8 @@ var ReactDOMInput = {
83
mountWrapper: function(inst, props) {
84
if (__DEV__) {
85
var owner = inst._currentElement._owner;
86
- ReactControlledValuePropTypes.checkPropTypes(
87
- 'input',
88
- props,
89
- owner ? owner.getName() : null,
90
- );
86
+ ReactControlledValuePropTypes.checkPropTypes('input', props, () =>
87
+ getStackAddendumByID(inst._debugID));
88
89
if (
90
props.checked !== undefined &&
src/renderers/dom/stack/client/wrappers/ReactDOMSelect.js
+8
-5
@@ -16,6 +16,12 @@ var ReactDOMComponentTree = require('ReactDOMComponentTree');
16
17
var warning = require('fbjs/lib/warning');
18
19
+if (__DEV__) {
20
+ var {
21
+ getStackAddendumByID,
22
+ } = require('ReactGlobalSharedState').ReactComponentTreeHook;
23
+}
24
+
25
var didWarnValueDefaultValue = false;
26
27
function getDeclarationErrorAddendum(owner) {
@@ -36,11 +42,8 @@ var valuePropNames = ['value', 'defaultValue'];
42
*/
43
function checkSelectPropTypes(inst, props) {
44
var owner = inst._currentElement._owner;
39
- ReactControlledValuePropTypes.checkPropTypes(
40
- 'select',
41
- props,
42
- owner ? owner.getName() : null,
43
- );
45
+ ReactControlledValuePropTypes.checkPropTypes('select', props, () =>
46
+ getStackAddendumByID(inst._debugID));
47
48
for (var i = 0; i < valuePropNames.length; i++) {
49
var propName = valuePropNames[i];
src/renderers/dom/stack/client/wrappers/ReactDOMTextarea.js
+8
-6
@@ -17,6 +17,12 @@ var ReactDOMComponentTree = require('ReactDOMComponentTree');
17
var invariant = require('fbjs/lib/invariant');
18
var warning = require('fbjs/lib/warning');
19
20
+if (__DEV__) {
21
+ var {
22
+ getStackAddendumByID,
23
+ } = require('ReactGlobalSharedState').ReactComponentTreeHook;
24
+}
25
+
26
var didWarnValDefaultVal = false;
27
28
/**
@@ -57,12 +63,8 @@ var ReactDOMTextarea = {
63
64
mountWrapper: function(inst, props) {
65
if (__DEV__) {
60
- var owner = inst._currentElement._owner;
61
- ReactControlledValuePropTypes.checkPropTypes(
62
- 'textarea',
63
- props,
64
- owner ? owner.getName() : null,
65
- );
66
+ ReactControlledValuePropTypes.checkPropTypes('textarea', props, () =>
67
+ getStackAddendumByID(inst._debugID));
68
if (
69
props.value !== undefined &&
70
props.defaultValue !== undefined &&