diff --git a/packages/react-dom/src/__tests__/ReactDOMInput-test.js b/packages/react-dom/src/__tests__/ReactDOMInput-test.js
index 7c36518857..98be58fa29 100644
--- a/packages/react-dom/src/__tests__/ReactDOMInput-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMInput-test.js
@@ -54,7 +54,7 @@ describe('ReactDOMInput', () => {
expect(() => {
ReactDOM.render(, container);
}).toErrorDev(
- 'Failed prop type: You provided a `value` prop to a form field without an `onChange` handler.',
+ 'Warning: You provided a `value` prop to a form field without an `onChange` handler.',
);
});
@@ -62,7 +62,7 @@ describe('ReactDOMInput', () => {
expect(() => {
ReactDOM.render(, container);
}).toErrorDev(
- 'Failed prop type: You provided a `value` prop to a form field without an `onChange` handler.',
+ 'Warning: You provided a `value` prop to a form field without an `onChange` handler.',
);
});
@@ -70,7 +70,7 @@ describe('ReactDOMInput', () => {
expect(() => {
ReactDOM.render(, container);
}).toErrorDev(
- 'Failed prop type: You provided a `value` prop to a form field without an `onChange` handler.',
+ 'Warning: You provided a `value` prop to a form field without an `onChange` handler.',
);
});
@@ -78,7 +78,7 @@ describe('ReactDOMInput', () => {
expect(() =>
ReactDOM.render(, container),
).toErrorDev(
- 'Failed prop type: You provided a `checked` prop to a form field without an `onChange` handler.',
+ 'Warning: You provided a `checked` prop to a form field without an `onChange` handler.',
);
});
@@ -95,7 +95,7 @@ describe('ReactDOMInput', () => {
container,
),
).toErrorDev(
- 'Failed prop type: You provided a `checked` prop to a form field without an `onChange` handler. ' +
+ 'Warning: You provided a `checked` prop to a form field without an `onChange` handler. ' +
'This will render a read-only field. If the field should be mutable use `defaultChecked`. ' +
'Otherwise, set either `onChange` or `readOnly`.',
);
@@ -125,7 +125,7 @@ describe('ReactDOMInput', () => {
expect(() => {
node = ReactDOM.render(, container);
}).toErrorDev(
- 'Failed prop type: You provided a `value` prop to a form field without an `onChange` handler.',
+ 'Warning: You provided a `value` prop to a form field without an `onChange` handler.',
);
setUntrackedValue.call(node, 'giraffe');
@@ -1172,7 +1172,7 @@ describe('ReactDOMInput', () => {
container,
),
).toErrorDev(
- 'Warning: Failed prop type: You provided a `value` prop to a form ' +
+ 'Warning: You provided a `value` prop to a form ' +
'field without an `onChange` handler. This will render a read-only ' +
'field. If the field should be mutable use `defaultValue`. ' +
'Otherwise, set either `onChange` or `readOnly`.\n' +
diff --git a/packages/react-dom/src/client/ReactDOMInput.js b/packages/react-dom/src/client/ReactDOMInput.js
index 884c2ad9df..93e263c5d3 100644
--- a/packages/react-dom/src/client/ReactDOMInput.js
+++ b/packages/react-dom/src/client/ReactDOMInput.js
@@ -14,7 +14,7 @@ import invariant from 'shared/invariant';
import {setValueForProperty} from './DOMPropertyOperations';
import {getFiberCurrentPropsFromNode} from './ReactDOMComponentTree';
import {getToStringValue, toString} from './ToStringValue';
-import ReactControlledValuePropTypes from '../shared/ReactControlledValuePropTypes';
+import {checkControlledValueProps} from '../shared/ReactControlledValuePropTypes';
import {updateValueIfChanged} from './inputValueTracking';
import {disableInputAttributeSyncing} from 'shared/ReactFeatureFlags';
@@ -73,7 +73,7 @@ export function getHostProps(element: Element, props: Object) {
export function initWrapperState(element: Element, props: Object) {
if (__DEV__) {
- ReactControlledValuePropTypes.checkPropTypes('input', props);
+ checkControlledValueProps('input', props);
if (
props.checked !== undefined &&
diff --git a/packages/react-dom/src/client/ReactDOMSelect.js b/packages/react-dom/src/client/ReactDOMSelect.js
index 0a8b179fe0..d97e01be0a 100644
--- a/packages/react-dom/src/client/ReactDOMSelect.js
+++ b/packages/react-dom/src/client/ReactDOMSelect.js
@@ -10,7 +10,7 @@
// TODO: direct imports like some-package/src/* are bad. Fix me.
import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber';
-import ReactControlledValuePropTypes from '../shared/ReactControlledValuePropTypes';
+import {checkControlledValueProps} from '../shared/ReactControlledValuePropTypes';
import {getToStringValue, toString} from './ToStringValue';
let didWarnValueDefaultValue;
@@ -38,7 +38,7 @@ const valuePropNames = ['value', 'defaultValue'];
*/
function checkSelectPropTypes(props) {
if (__DEV__) {
- ReactControlledValuePropTypes.checkPropTypes('select', props);
+ checkControlledValueProps('select', props);
for (let i = 0; i < valuePropNames.length; i++) {
const propName = valuePropNames[i];
diff --git a/packages/react-dom/src/client/ReactDOMTextarea.js b/packages/react-dom/src/client/ReactDOMTextarea.js
index 9c1505bac6..a37c36b94e 100644
--- a/packages/react-dom/src/client/ReactDOMTextarea.js
+++ b/packages/react-dom/src/client/ReactDOMTextarea.js
@@ -9,7 +9,7 @@
import invariant from 'shared/invariant';
-import ReactControlledValuePropTypes from '../shared/ReactControlledValuePropTypes';
+import {checkControlledValueProps} from '../shared/ReactControlledValuePropTypes';
import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber';
import {getToStringValue, toString} from './ToStringValue';
import type {ToStringValue} from './ToStringValue';
@@ -64,7 +64,7 @@ export function getHostProps(element: Element, props: Object) {
export function initWrapperState(element: Element, props: Object) {
const node = ((element: any): TextAreaWithWrapperState);
if (__DEV__) {
- ReactControlledValuePropTypes.checkPropTypes('textarea', props);
+ checkControlledValueProps('textarea', props);
if (
props.value !== undefined &&
props.defaultValue !== undefined &&
diff --git a/packages/react-dom/src/server/ReactPartialRenderer.js b/packages/react-dom/src/server/ReactPartialRenderer.js
index d0dcd435f1..4393208f27 100644
--- a/packages/react-dom/src/server/ReactPartialRenderer.js
+++ b/packages/react-dom/src/server/ReactPartialRenderer.js
@@ -67,7 +67,7 @@ import {
getIntrinsicNamespace,
getChildNamespace,
} from '../shared/DOMNamespaces';
-import ReactControlledValuePropTypes from '../shared/ReactControlledValuePropTypes';
+import {checkControlledValueProps} from '../shared/ReactControlledValuePropTypes';
import assertValidProps from '../shared/assertValidProps';
import dangerousStyleValue from '../shared/dangerousStyleValue';
import hyphenateStyleName from '../shared/hyphenateStyleName';
@@ -1358,7 +1358,7 @@ class ReactDOMServerRenderer {
let props = element.props;
if (tag === 'input') {
if (__DEV__) {
- ReactControlledValuePropTypes.checkPropTypes('input', props);
+ checkControlledValueProps('input', props);
if (
props.checked !== undefined &&
@@ -1410,7 +1410,7 @@ class ReactDOMServerRenderer {
);
} else if (tag === 'textarea') {
if (__DEV__) {
- ReactControlledValuePropTypes.checkPropTypes('textarea', props);
+ checkControlledValueProps('textarea', props);
if (
props.value !== undefined &&
props.defaultValue !== undefined &&
@@ -1465,7 +1465,7 @@ class ReactDOMServerRenderer {
});
} else if (tag === 'select') {
if (__DEV__) {
- ReactControlledValuePropTypes.checkPropTypes('select', props);
+ checkControlledValueProps('select', props);
for (let i = 0; i < valuePropNames.length; i++) {
const propName = valuePropNames[i];
diff --git a/packages/react-dom/src/shared/ReactControlledValuePropTypes.js b/packages/react-dom/src/shared/ReactControlledValuePropTypes.js
index 60df6ab2e5..c15c4a94aa 100644
--- a/packages/react-dom/src/shared/ReactControlledValuePropTypes.js
+++ b/packages/react-dom/src/shared/ReactControlledValuePropTypes.js
@@ -5,81 +5,57 @@
* LICENSE file in the root directory of this source tree.
*/
-import checkPropTypes from 'shared/checkPropTypes';
-import ReactSharedInternals from 'shared/ReactSharedInternals';
import {enableDeprecatedFlareAPI} from 'shared/ReactFeatureFlags';
-let ReactDebugCurrentFrame = null;
-
-const ReactControlledValuePropTypes = {
- checkPropTypes: null,
+const hasReadOnlyValue = {
+ button: true,
+ checkbox: true,
+ image: true,
+ hidden: true,
+ radio: true,
+ reset: true,
+ submit: true,
};
-if (__DEV__) {
- ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
-
- const hasReadOnlyValue = {
- button: true,
- checkbox: true,
- image: true,
- hidden: true,
- radio: true,
- reset: true,
- submit: true,
- };
-
- const propTypes = {
- value: function(props, propName, componentName) {
- if (
+export function checkControlledValueProps(
+ tagName: string,
+ props: Object,
+): void {
+ if (__DEV__) {
+ if (
+ !(
hasReadOnlyValue[props.type] ||
props.onChange ||
props.onInput ||
props.readOnly ||
props.disabled ||
- props[propName] == null ||
+ props.value == null ||
(enableDeprecatedFlareAPI && props.DEPRECATED_flareListeners)
- ) {
- return null;
- }
- return new Error(
+ )
+ ) {
+ console.error(
'You provided a `value` prop to a form field without an ' +
'`onChange` handler. This will render a read-only field. If ' +
'the field should be mutable use `defaultValue`. Otherwise, ' +
'set either `onChange` or `readOnly`.',
);
- },
- checked: function(props, propName, componentName) {
- if (
+ }
+
+ if (
+ !(
props.onChange ||
props.readOnly ||
props.disabled ||
- props[propName] == null ||
+ props.checked == null ||
(enableDeprecatedFlareAPI && props.DEPRECATED_flareListeners)
- ) {
- return null;
- }
- return new Error(
+ )
+ ) {
+ console.error(
'You provided a `checked` prop to a form field without an ' +
'`onChange` handler. This will render a read-only field. If ' +
'the field should be mutable use `defaultChecked`. Otherwise, ' +
'set either `onChange` or `readOnly`.',
);
- },
- };
-
- /**
- * Provide a linked `value` attribute for controlled forms. You should not use
- * this outside of the ReactDOM controlled form components.
- */
- ReactControlledValuePropTypes.checkPropTypes = function(tagName, props) {
- checkPropTypes(
- propTypes,
- props,
- 'prop',
- tagName,
- ReactDebugCurrentFrame.getStackAddendum,
- );
- };
+ }
+ }
}
-
-export default ReactControlledValuePropTypes;