diff --git a/src/renderers/dom/client/wrappers/ReactDOMInput.js b/src/renderers/dom/client/wrappers/ReactDOMInput.js
index 69d797b7cdf3f..4728bddbe8929 100644
--- a/src/renderers/dom/client/wrappers/ReactDOMInput.js
+++ b/src/renderers/dom/client/wrappers/ReactDOMInput.js
@@ -25,6 +25,8 @@ var instancesByReactID = {};
var didWarnValueLink = false;
var didWarnCheckedLink = false;
var didWarnValueNull = false;
+var didWarnValueDefaultValue = false;
+var didWarnCheckedDefaultChecked = false;
function forceUpdateIfMounted() {
if (this._rootNodeID) {
@@ -104,6 +106,28 @@ var ReactDOMInput = {
);
didWarnCheckedLink = true;
}
+ if (props.checked !== undefined && props.defaultChecked !== undefined &&
+ !didWarnCheckedDefaultChecked) {
+ warning(
+ false,
+ 'Input elements must be either controlled or uncontrolled (specify either the ' +
+ 'checked prop, or the defaultChecked prop, but not both). Decide between using a ' +
+ 'controlled or uncontrolled input and remove one of these props. More info: ' +
+ 'https://fb.me/react-controlled-components'
+ );
+ didWarnCheckedDefaultChecked = true;
+ }
+ if (props.value !== undefined && props.defaultValue !== undefined &&
+ !didWarnValueDefaultValue) {
+ warning(
+ false,
+ 'Input elements must be either controlled or uncontrolled (specify either the value ' +
+ 'prop, or the defaultValue prop, but not both). Decide between using a controlled ' +
+ 'or uncontrolled input and remove one of these props. More info: ' +
+ 'https://fb.me/react-controlled-components'
+ );
+ didWarnValueDefaultValue = true;
+ }
warnIfValueIsNull(props);
}
diff --git a/src/renderers/dom/client/wrappers/ReactDOMSelect.js b/src/renderers/dom/client/wrappers/ReactDOMSelect.js
index 1bfa652af80a5..1ef4ccd5b739d 100644
--- a/src/renderers/dom/client/wrappers/ReactDOMSelect.js
+++ b/src/renderers/dom/client/wrappers/ReactDOMSelect.js
@@ -20,6 +20,7 @@ var warning = require('warning');
var didWarnValueLink = false;
var didWarnValueNull = false;
+var didWarnValueDefaultValue = false;
function updateOptionsIfPendingUpdateAndMounted() {
if (this._rootNodeID && this._wrapperState.pendingUpdate) {
@@ -178,6 +179,18 @@ var ReactDOMSelect = {
onChange: _handleChange.bind(inst),
wasMultiple: Boolean(props.multiple),
};
+
+ if (props.value !== undefined && props.defaultValue !== undefined &&
+ !didWarnValueDefaultValue) {
+ warning(
+ false,
+ 'Select elements must be either controlled or uncontrolled (specify either the ' +
+ 'value prop, or the defaultValue prop, but not both). Decide between using a ' +
+ 'controlled or uncontrolled select element and remove one of these props. More info: ' +
+ 'https://fb.me/react-controlled-components'
+ );
+ didWarnValueDefaultValue = true;
+ }
},
getSelectValueContext: function(inst) {
diff --git a/src/renderers/dom/client/wrappers/ReactDOMTextarea.js b/src/renderers/dom/client/wrappers/ReactDOMTextarea.js
index f3e9285f9300d..5ed80996cf428 100644
--- a/src/renderers/dom/client/wrappers/ReactDOMTextarea.js
+++ b/src/renderers/dom/client/wrappers/ReactDOMTextarea.js
@@ -22,6 +22,7 @@ var warning = require('warning');
var didWarnValueLink = false;
var didWarnValueNull = false;
+var didWarnValDefaultVal = false;
function forceUpdateIfMounted() {
if (this._rootNodeID) {
@@ -91,6 +92,16 @@ var ReactDOMTextarea = {
);
didWarnValueLink = true;
}
+ if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
+ warning(
+ false,
+ 'Textarea elements must be either controlled or uncontrolled (specify either the value ' +
+ 'prop, or the defaultValue prop, but not both). Decide between using a controlled or ' +
+ 'uncontrolled input and remove one of these props. More info: ' +
+ 'https://fb.me/react-controlled-components'
+ );
+ didWarnValDefaultVal = true;
+ }
warnIfValueIsNull(props);
}
diff --git a/src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js b/src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js
index f3fd0a2371399..d9463b70cfac1 100644
--- a/src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js
+++ b/src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js
@@ -415,6 +415,40 @@ describe('ReactDOMInput', function() {
expect(console.error.argsForCall.length).toBe(1);
});
+ it('should throw warning message if checked and defaultChecked props are specified', function() {
+ ReactTestUtils.renderIntoDocument(
+
+ );
+ expect(console.error.argsForCall[0][0]).toContain(
+ 'Input elements must be either controlled or uncontrolled (specify either the ' +
+ 'checked prop, or the defaultChecked prop, but not both). Decide between using a ' +
+ 'controlled or uncontrolled input and remove one of these props. More info: ' +
+ 'https://fb.me/react-controlled-components'
+ );
+
+ ReactTestUtils.renderIntoDocument(
+
+ );
+ expect(console.error.argsForCall.length).toBe(1);
+ });
+
+ it('should throw warning message if value and defaultValue props are specified', function() {
+ ReactTestUtils.renderIntoDocument(
+
+ );
+ expect(console.error.argsForCall[0][0]).toContain(
+ 'Input elements must be either controlled or uncontrolled (specify either the value ' +
+ 'prop, or the defaultValue prop, but not both). Decide between using a controlled or ' +
+ 'uncontrolled input and remove one of these props. More info: ' +
+ 'https://fb.me/react-controlled-components'
+ );
+
+ ReactTestUtils.renderIntoDocument(
+
+ );
+ expect(console.error.argsForCall.length).toBe(1);
+ });
+
it('sets type before value always', function() {
var log = [];
var originalCreateElement = document.createElement;
diff --git a/src/renderers/dom/client/wrappers/__tests__/ReactDOMSelect-test.js b/src/renderers/dom/client/wrappers/__tests__/ReactDOMSelect-test.js
index f132b81846255..6de9e25f9745b 100644
--- a/src/renderers/dom/client/wrappers/__tests__/ReactDOMSelect-test.js
+++ b/src/renderers/dom/client/wrappers/__tests__/ReactDOMSelect-test.js
@@ -490,4 +490,30 @@ describe('ReactDOMSelect', function() {
expect(node.value).toBe('giraffe');
});
+
+ it('should throw warning message if value and defaultValue props are specified', function() {
+ spyOn(console, 'error');
+ ReactTestUtils.renderIntoDocument(
+
+ );
+ expect(console.error.argsForCall[0][0]).toContain(
+ 'Select elements must be either controlled or uncontrolled (specify either the ' +
+ 'value prop, or the defaultValue prop, but not both). Decide between using a ' +
+ 'controlled or uncontrolled select element and remove one of these props. More info: ' +
+ 'https://fb.me/react-controlled-components'
+ );
+
+ ReactTestUtils.renderIntoDocument(
+
+ );
+ expect(console.error.argsForCall.length).toBe(1);
+ });
});
diff --git a/src/renderers/dom/client/wrappers/__tests__/ReactDOMTextarea-test.js b/src/renderers/dom/client/wrappers/__tests__/ReactDOMTextarea-test.js
index 226e556da8f84..b6b9a17a67725 100644
--- a/src/renderers/dom/client/wrappers/__tests__/ReactDOMTextarea-test.js
+++ b/src/renderers/dom/client/wrappers/__tests__/ReactDOMTextarea-test.js
@@ -278,4 +278,22 @@ describe('ReactDOMTextarea', function() {
ReactTestUtils.renderIntoDocument();
expect(console.error.argsForCall.length).toBe(1);
});
+
+ it('should throw warning message if value and defaultValue are specified', function() {
+ spyOn(console, 'error');
+ ReactTestUtils.renderIntoDocument(
+
+ );
+ expect(console.error.argsForCall[0][0]).toContain(
+ 'Textarea elements must be either controlled or uncontrolled (specify either the value ' +
+ 'prop, or the defaultValue prop, but not both). Decide between using a controlled or ' +
+ 'uncontrolled input and remove one of these props. More info: ' +
+ 'https://fb.me/react-controlled-components'
+ );
+
+ ReactTestUtils.renderIntoDocument(
+
+ );
+ expect(console.error.argsForCall.length).toBe(1);
+ });
});