diff --git a/src/renderers/dom/client/wrappers/ReactDOMInput.js b/src/renderers/dom/client/wrappers/ReactDOMInput.js
index dfa860a2dbe15..4350b4b050181 100644
--- a/src/renderers/dom/client/wrappers/ReactDOMInput.js
+++ b/src/renderers/dom/client/wrappers/ReactDOMInput.js
@@ -36,7 +36,7 @@ function forceUpdateIfMounted() {
function isControlled(props) {
var usesChecked = props.type === 'checkbox' || props.type === 'radio';
- return usesChecked ? props.checked !== undefined : props.value !== undefined;
+ return usesChecked ? props.checked != null : props.value != null;
}
/**
diff --git a/src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js b/src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js
index 797841df73e41..f138e12e75e55 100644
--- a/src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js
+++ b/src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js
@@ -580,7 +580,7 @@ describe('ReactDOMInput', function() {
expect(console.error.calls.count()).toBe(1);
});
- it('should warn if controlled input switches to uncontrolled', function() {
+ it('should warn if controlled input switches to uncontrolled (value is undefined)', function() {
var stub = ;
var container = document.createElement('div');
ReactDOM.render(stub, container);
@@ -594,6 +594,20 @@ describe('ReactDOMInput', function() {
);
});
+ it('should warn if controlled input switches to uncontrolled (value is null)', function() {
+ var stub = ;
+ var container = document.createElement('div');
+ ReactDOM.render(stub, container);
+ ReactDOM.render(, container);
+ expect(console.error.calls.count()).toBeGreaterThan(0);
+ expect(console.error.calls.argsFor(1)[0]).toContain(
+ 'A component is changing a controlled input of type text to be uncontrolled. ' +
+ 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
+ 'Decide between using a controlled or uncontrolled input ' +
+ 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components'
+ );
+ });
+
it('should warn if controlled input switches to uncontrolled with defaultValue', function() {
var stub = ;
var container = document.createElement('div');
@@ -608,7 +622,7 @@ describe('ReactDOMInput', function() {
);
});
- it('should warn if uncontrolled input switches to controlled', function() {
+ it('should warn if uncontrolled input (value is undefined) switches to controlled', function() {
var stub = ;
var container = document.createElement('div');
ReactDOM.render(stub, container);
@@ -622,7 +636,21 @@ describe('ReactDOMInput', function() {
);
});
- it('should warn if controlled checkbox switches to uncontrolled', function() {
+ it('should warn if uncontrolled input (value is null) switches to controlled', function() {
+ var stub = ;
+ var container = document.createElement('div');
+ ReactDOM.render(stub, container);
+ ReactDOM.render(, container);
+ expect(console.error.calls.count()).toBeGreaterThan(0);
+ expect(console.error.calls.argsFor(1)[0]).toContain(
+ 'A component is changing an uncontrolled input of type text to be controlled. ' +
+ 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
+ 'Decide between using a controlled or uncontrolled input ' +
+ 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components'
+ );
+ });
+
+ it('should warn if controlled checkbox switches to uncontrolled (checked is undefined)', function() {
var stub = ;
var container = document.createElement('div');
ReactDOM.render(stub, container);
@@ -636,6 +664,20 @@ describe('ReactDOMInput', function() {
);
});
+ it('should warn if controlled checkbox switches to uncontrolled (checked is null)', function() {
+ var stub = ;
+ var container = document.createElement('div');
+ ReactDOM.render(stub, container);
+ ReactDOM.render(, container);
+ expect(console.error.calls.count()).toBe(1);
+ expect(console.error.calls.argsFor(0)[0]).toContain(
+ 'A component is changing a controlled input of type checkbox to be uncontrolled. ' +
+ 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
+ 'Decide between using a controlled or uncontrolled input ' +
+ 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components'
+ );
+ });
+
it('should warn if controlled checkbox switches to uncontrolled with defaultChecked', function() {
var stub = ;
var container = document.createElement('div');
@@ -650,7 +692,7 @@ describe('ReactDOMInput', function() {
);
});
- it('should warn if uncontrolled checkbox switches to controlled', function() {
+ it('should warn if uncontrolled checkbox (checked is undefined) switches to controlled', function() {
var stub = ;
var container = document.createElement('div');
ReactDOM.render(stub, container);
@@ -664,7 +706,21 @@ describe('ReactDOMInput', function() {
);
});
- it('should warn if controlled radio switches to uncontrolled', function() {
+ it('should warn if uncontrolled checkbox (checked is null) switches to controlled', function() {
+ var stub = ;
+ var container = document.createElement('div');
+ ReactDOM.render(stub, container);
+ ReactDOM.render(, container);
+ expect(console.error.calls.count()).toBe(1);
+ expect(console.error.calls.argsFor(0)[0]).toContain(
+ 'A component is changing an uncontrolled input of type checkbox to be controlled. ' +
+ 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
+ 'Decide between using a controlled or uncontrolled input ' +
+ 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components'
+ );
+ });
+
+ it('should warn if controlled radio switches to uncontrolled (checked is undefined)', function() {
var stub = ;
var container = document.createElement('div');
ReactDOM.render(stub, container);
@@ -678,6 +734,20 @@ describe('ReactDOMInput', function() {
);
});
+ it('should warn if controlled radio switches to uncontrolled (checked is null)', function() {
+ var stub = ;
+ var container = document.createElement('div');
+ ReactDOM.render(stub, container);
+ ReactDOM.render(, container);
+ expect(console.error.calls.count()).toBe(1);
+ expect(console.error.calls.argsFor(0)[0]).toContain(
+ 'A component is changing a controlled input of type radio to be uncontrolled. ' +
+ 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' +
+ 'Decide between using a controlled or uncontrolled input ' +
+ 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components'
+ );
+ });
+
it('should warn if controlled radio switches to uncontrolled with defaultChecked', function() {
var stub = ;
var container = document.createElement('div');
@@ -692,7 +762,7 @@ describe('ReactDOMInput', function() {
);
});
- it('should warn if uncontrolled radio switches to controlled', function() {
+ it('should warn if uncontrolled radio (checked is undefined) switches to controlled', function() {
var stub = ;
var container = document.createElement('div');
ReactDOM.render(stub, container);
@@ -706,6 +776,20 @@ describe('ReactDOMInput', function() {
);
});
+ it('should warn if uncontrolled radio (checked is null) switches to controlled', function() {
+ var stub = ;
+ var container = document.createElement('div');
+ ReactDOM.render(stub, container);
+ ReactDOM.render(, container);
+ expect(console.error.calls.count()).toBe(1);
+ expect(console.error.calls.argsFor(0)[0]).toContain(
+ 'A component is changing an uncontrolled input of type radio to be controlled. ' +
+ 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' +
+ 'Decide between using a controlled or uncontrolled input ' +
+ 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components'
+ );
+ });
+
it('should not warn if radio value changes but never becomes controlled', function() {
var container = document.createElement('div');
ReactDOM.render(, container);