diff --git a/src/renderers/dom/client/wrappers/ReactDOMInput.js b/src/renderers/dom/client/wrappers/ReactDOMInput.js
index e309fd6191a76..031faf14b6673 100644
--- a/src/renderers/dom/client/wrappers/ReactDOMInput.js
+++ b/src/renderers/dom/client/wrappers/ReactDOMInput.js
@@ -24,6 +24,7 @@ var instancesByReactID = {};
var didWarnValueLink = false;
var didWarnCheckedLink = false;
+var didWarnValueNull = false;
function forceUpdateIfMounted() {
if (this._rootNodeID) {
@@ -32,6 +33,19 @@ function forceUpdateIfMounted() {
}
}
+function warnIfValueIsNull(props) {
+ if (props != null && props.value === null && !didWarnValueNull) {
+ warning(
+ false,
+ '`value` prop on `input` should not be null. ' +
+ 'Consider using the empty string to clear the component or' +
+ ' `undefined` for uncontrolled components.'
+ );
+
+ didWarnValueNull = true;
+ }
+}
+
/**
* Implements an native component that allows setting these optional
* props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
@@ -86,6 +100,7 @@ var ReactDOMInput = {
);
didWarnCheckedLink = true;
}
+ warnIfValueIsNull(props);
}
var defaultValue = props.defaultValue;
@@ -108,6 +123,10 @@ var ReactDOMInput = {
updateWrapper: function(inst) {
var props = inst._currentElement.props;
+ if (__DEV__) {
+ warnIfValueIsNull(props);
+ }
+
// TODO: Shouldn't this be getChecked(props)?
var checked = props.checked;
if (checked != null) {
diff --git a/src/renderers/dom/client/wrappers/ReactDOMSelect.js b/src/renderers/dom/client/wrappers/ReactDOMSelect.js
index 96c1098c66370..7d970714a3a5d 100644
--- a/src/renderers/dom/client/wrappers/ReactDOMSelect.js
+++ b/src/renderers/dom/client/wrappers/ReactDOMSelect.js
@@ -19,6 +19,7 @@ var assign = require('Object.assign');
var warning = require('warning');
var didWarnValueLink = false;
+var didWarnValueNull = false;
function updateOptionsIfPendingUpdateAndMounted() {
if (this._rootNodeID && this._wrapperState.pendingUpdate) {
@@ -43,6 +44,19 @@ function getDeclarationErrorAddendum(owner) {
return '';
}
+function warnIfValueIsNull(props) {
+ if (props != null && props.value === null && !didWarnValueNull) {
+ warning(
+ false,
+ '`value` prop on `select` should not be null. ' +
+ 'Consider using the empty string to clear the component or' +
+ ' `undefined` for uncontrolled components.'
+ );
+
+ didWarnValueNull = true;
+ }
+}
+
var valuePropNames = ['value', 'defaultValue'];
/**
@@ -153,6 +167,7 @@ var ReactDOMSelect = {
mountWrapper: function(inst, props) {
if (__DEV__) {
checkSelectPropTypes(inst, props);
+ warnIfValueIsNull(props);
}
var value = LinkedValueUtils.getValue(props);
@@ -172,6 +187,9 @@ var ReactDOMSelect = {
postUpdateWrapper: function(inst) {
var props = inst._currentElement.props;
+ if (__DEV__) {
+ warnIfValueIsNull(props);
+ }
// After the initial mount, we control selected-ness manually so don't pass
// this value down
diff --git a/src/renderers/dom/client/wrappers/ReactDOMTextarea.js b/src/renderers/dom/client/wrappers/ReactDOMTextarea.js
index 26ac1dd4de626..f5a1b97806d52 100644
--- a/src/renderers/dom/client/wrappers/ReactDOMTextarea.js
+++ b/src/renderers/dom/client/wrappers/ReactDOMTextarea.js
@@ -20,6 +20,7 @@ var invariant = require('invariant');
var warning = require('warning');
var didWarnValueLink = false;
+var didWarnValueNull = false;
function forceUpdateIfMounted() {
if (this._rootNodeID) {
@@ -28,6 +29,19 @@ function forceUpdateIfMounted() {
}
}
+function warnIfValueIsNull(props) {
+ if (props != null && props.value === null && !didWarnValueNull) {
+ warning(
+ false,
+ '`value` prop on `textarea` should not be null. ' +
+ 'Consider using the empty string to clear the component or' +
+ ' `undefined` for uncontrolled components.'
+ );
+
+ didWarnValueNull = true;
+ }
+}
+
/**
* Implements a