Don't use checkPropTypes for internals (#18488)
We use console.error for internal warnings.
Sebastian Markbåge committed
Apr 4, 2020 at 15:10 UTC
1fd45437d781b1b905be2308447aa7793bbcb571
6 files changed
+46
-70
packages/react-dom/src/__tests__/ReactDOMInput-test.js
+7
-7
@@ -54,7 +54,7 @@ describe('ReactDOMInput', () => {
54
expect(() => {
55
ReactDOM.render(<input type="text" value={0} />, container);
56
}).toErrorDev(
57
- 'Failed prop type: You provided a `value` prop to a form field without an `onChange` handler.',
57
+ 'Warning: You provided a `value` prop to a form field without an `onChange` handler.',
58
);
59
});
60
@@ -62,7 +62,7 @@ describe('ReactDOMInput', () => {
62
expect(() => {
63
ReactDOM.render(<input type="text" value="" />, container);
64
}).toErrorDev(
65
- 'Failed prop type: You provided a `value` prop to a form field without an `onChange` handler.',
65
+ 'Warning: You provided a `value` prop to a form field without an `onChange` handler.',
66
);
67
});
68
@@ -70,7 +70,7 @@ describe('ReactDOMInput', () => {
70
expect(() => {
71
ReactDOM.render(<input type="text" value="0" />, container);
72
}).toErrorDev(
73
- 'Failed prop type: You provided a `value` prop to a form field without an `onChange` handler.',
73
+ 'Warning: You provided a `value` prop to a form field without an `onChange` handler.',
74
);
75
});
76
@@ -78,7 +78,7 @@ describe('ReactDOMInput', () => {
78
expect(() =>
79
ReactDOM.render(<input type="checkbox" checked={false} />, container),
80
).toErrorDev(
81
- 'Failed prop type: You provided a `checked` prop to a form field without an `onChange` handler.',
81
+ 'Warning: You provided a `checked` prop to a form field without an `onChange` handler.',
82
);
83
});
84
@@ -95,7 +95,7 @@ describe('ReactDOMInput', () => {
95
container,
96
),
97
).toErrorDev(
98
- 'Failed prop type: You provided a `checked` prop to a form field without an `onChange` handler. ' +
98
+ 'Warning: You provided a `checked` prop to a form field without an `onChange` handler. ' +
99
'This will render a read-only field. If the field should be mutable use `defaultChecked`. ' +
100
'Otherwise, set either `onChange` or `readOnly`.',
101
);
@@ -125,7 +125,7 @@ describe('ReactDOMInput', () => {
125
expect(() => {
126
node = ReactDOM.render(<input type="text" value="lion" />, container);
127
}).toErrorDev(
128
- 'Failed prop type: You provided a `value` prop to a form field without an `onChange` handler.',
128
+ 'Warning: You provided a `value` prop to a form field without an `onChange` handler.',
129
);
130
131
setUntrackedValue.call(node, 'giraffe');
@@ -1172,7 +1172,7 @@ describe('ReactDOMInput', () => {
1172
container,
1173
),
1174
).toErrorDev(
1175
- 'Warning: Failed prop type: You provided a `value` prop to a form ' +
1175
+ 'Warning: You provided a `value` prop to a form ' +
1176
'field without an `onChange` handler. This will render a read-only ' +
1177
'field. If the field should be mutable use `defaultValue`. ' +
1178
'Otherwise, set either `onChange` or `readOnly`.\n' +
packages/react-dom/src/client/ReactDOMInput.js
+2
-2
@@ -14,7 +14,7 @@ import invariant from 'shared/invariant';
14
import {setValueForProperty} from './DOMPropertyOperations';
15
import {getFiberCurrentPropsFromNode} from './ReactDOMComponentTree';
16
import {getToStringValue, toString} from './ToStringValue';
17
-import ReactControlledValuePropTypes from '../shared/ReactControlledValuePropTypes';
17
+import {checkControlledValueProps} from '../shared/ReactControlledValuePropTypes';
18
import {updateValueIfChanged} from './inputValueTracking';
19
import {disableInputAttributeSyncing} from 'shared/ReactFeatureFlags';
20
@@ -73,7 +73,7 @@ export function getHostProps(element: Element, props: Object) {
73
74
export function initWrapperState(element: Element, props: Object) {
75
if (__DEV__) {
76
- ReactControlledValuePropTypes.checkPropTypes('input', props);
76
+ checkControlledValueProps('input', props);
77
78
if (
79
props.checked !== undefined &&
packages/react-dom/src/client/ReactDOMSelect.js
+2
-2
@@ -10,7 +10,7 @@
10
// TODO: direct imports like some-package/src/* are bad. Fix me.
11
import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber';
12
13
-import ReactControlledValuePropTypes from '../shared/ReactControlledValuePropTypes';
13
+import {checkControlledValueProps} from '../shared/ReactControlledValuePropTypes';
14
import {getToStringValue, toString} from './ToStringValue';
15
16
let didWarnValueDefaultValue;
@@ -38,7 +38,7 @@ const valuePropNames = ['value', 'defaultValue'];
38
*/
39
function checkSelectPropTypes(props) {
40
if (__DEV__) {
41
- ReactControlledValuePropTypes.checkPropTypes('select', props);
41
+ checkControlledValueProps('select', props);
42
43
for (let i = 0; i < valuePropNames.length; i++) {
44
const propName = valuePropNames[i];
packages/react-dom/src/client/ReactDOMTextarea.js
+2
-2
@@ -9,7 +9,7 @@
9
10
import invariant from 'shared/invariant';
11
12
-import ReactControlledValuePropTypes from '../shared/ReactControlledValuePropTypes';
12
+import {checkControlledValueProps} from '../shared/ReactControlledValuePropTypes';
13
import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber';
14
import {getToStringValue, toString} from './ToStringValue';
15
import type {ToStringValue} from './ToStringValue';
@@ -64,7 +64,7 @@ export function getHostProps(element: Element, props: Object) {
64
export function initWrapperState(element: Element, props: Object) {
65
const node = ((element: any): TextAreaWithWrapperState);
66
if (__DEV__) {
67
- ReactControlledValuePropTypes.checkPropTypes('textarea', props);
67
+ checkControlledValueProps('textarea', props);
68
if (
69
props.value !== undefined &&
70
props.defaultValue !== undefined &&
packages/react-dom/src/server/ReactPartialRenderer.js
+4
-4
@@ -67,7 +67,7 @@ import {
67
getIntrinsicNamespace,
68
getChildNamespace,
69
} from '../shared/DOMNamespaces';
70
-import ReactControlledValuePropTypes from '../shared/ReactControlledValuePropTypes';
70
+import {checkControlledValueProps} from '../shared/ReactControlledValuePropTypes';
71
import assertValidProps from '../shared/assertValidProps';
72
import dangerousStyleValue from '../shared/dangerousStyleValue';
73
import hyphenateStyleName from '../shared/hyphenateStyleName';
@@ -1358,7 +1358,7 @@ class ReactDOMServerRenderer {
1358
let props = element.props;
1359
if (tag === 'input') {
1360
if (__DEV__) {
1361
- ReactControlledValuePropTypes.checkPropTypes('input', props);
1361
+ checkControlledValueProps('input', props);
1362
1363
if (
1364
props.checked !== undefined &&
@@ -1410,7 +1410,7 @@ class ReactDOMServerRenderer {
1410
);
1411
} else if (tag === 'textarea') {
1412
if (__DEV__) {
1413
- ReactControlledValuePropTypes.checkPropTypes('textarea', props);
1413
+ checkControlledValueProps('textarea', props);
1414
if (
1415
props.value !== undefined &&
1416
props.defaultValue !== undefined &&
@@ -1465,7 +1465,7 @@ class ReactDOMServerRenderer {
1465
});
1466
} else if (tag === 'select') {
1467
if (__DEV__) {
1468
- ReactControlledValuePropTypes.checkPropTypes('select', props);
1468
+ checkControlledValueProps('select', props);
1469
1470
for (let i = 0; i < valuePropNames.length; i++) {
1471
const propName = valuePropNames[i];
packages/react-dom/src/shared/ReactControlledValuePropTypes.js
+29
-53
@@ -5,81 +5,57 @@
5
* LICENSE file in the root directory of this source tree.
6
*/
7
8
-import checkPropTypes from 'shared/checkPropTypes';
9
-import ReactSharedInternals from 'shared/ReactSharedInternals';
8
import {enableDeprecatedFlareAPI} from 'shared/ReactFeatureFlags';
9
12
-let ReactDebugCurrentFrame = null;
13
-
14
-const ReactControlledValuePropTypes = {
15
- checkPropTypes: null,
10
+const hasReadOnlyValue = {
11
+ button: true,
12
+ checkbox: true,
13
+ image: true,
14
+ hidden: true,
15
+ radio: true,
16
+ reset: true,
17
+ submit: true,
18
};
19
18
-if (__DEV__) {
19
- ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
20
-
21
- const hasReadOnlyValue = {
22
- button: true,
23
- checkbox: true,
24
- image: true,
25
- hidden: true,
26
- radio: true,
27
- reset: true,
28
- submit: true,
29
- };
30
-
31
- const propTypes = {
32
- value: function(props, propName, componentName) {
33
- if (
20
+export function checkControlledValueProps(
21
+ tagName: string,
22
+ props: Object,
23
+): void {
24
+ if (__DEV__) {
25
+ if (
26
+ !(
27
hasReadOnlyValue[props.type] ||
28
props.onChange ||
29
props.onInput ||
30
props.readOnly ||
31
props.disabled ||
39
- props[propName] == null ||
32
+ props.value == null ||
33
(enableDeprecatedFlareAPI && props.DEPRECATED_flareListeners)
41
- ) {
42
- return null;
43
- }
44
- return new Error(
34
+ )
35
+ ) {
36
+ console.error(
37
'You provided a `value` prop to a form field without an ' +
38
'`onChange` handler. This will render a read-only field. If ' +
39
'the field should be mutable use `defaultValue`. Otherwise, ' +
40
'set either `onChange` or `readOnly`.',
41
);
50
- },
51
- checked: function(props, propName, componentName) {
52
- if (
42
+ }
43
+
44
+ if (
45
+ !(
46
props.onChange ||
47
props.readOnly ||
48
props.disabled ||
56
- props[propName] == null ||
49
+ props.checked == null ||
50
(enableDeprecatedFlareAPI && props.DEPRECATED_flareListeners)
58
- ) {
59
- return null;
60
- }
61
- return new Error(
51
+ )
52
+ ) {
53
+ console.error(
54
'You provided a `checked` prop to a form field without an ' +
55
'`onChange` handler. This will render a read-only field. If ' +
56
'the field should be mutable use `defaultChecked`. Otherwise, ' +
57
'set either `onChange` or `readOnly`.',
58
);
67
- },
68
- };
69
-
70
- /**
71
- * Provide a linked `value` attribute for controlled forms. You should not use
72
- * this outside of the ReactDOM controlled form components.
73
- */
74
- ReactControlledValuePropTypes.checkPropTypes = function(tagName, props) {
75
- checkPropTypes(
76
- propTypes,
77
- props,
78
- 'prop',
79
- tagName,
80
- ReactDebugCurrentFrame.getStackAddendum,
81
- );
82
- };
59
+ }
60
+ }
61
}
84
-
85
-export default ReactControlledValuePropTypes;