diff --git a/scripts/fiber/tests-passing.txt b/scripts/fiber/tests-passing.txt
index 111ea1692e20..c0a53983ff00 100644
--- a/scripts/fiber/tests-passing.txt
+++ b/scripts/fiber/tests-passing.txt
@@ -1536,6 +1536,8 @@ src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
* should allow setting `value` to `false`
* should allow setting `value` to `objToString`
* should not incur unnecessary DOM mutations
+* should not incur unnecessary DOM mutations for numeric type conversion
+* should not incur unnecessary DOM mutations for the boolean type conversion
* should properly control a value of number `0`
* should properly control 0.0 for a text input
* should properly control 0.0 for a number input
diff --git a/src/renderers/dom/fiber/wrappers/ReactDOMFiberInput.js b/src/renderers/dom/fiber/wrappers/ReactDOMFiberInput.js
index 41de9687e429..6d5387e25660 100644
--- a/src/renderers/dom/fiber/wrappers/ReactDOMFiberInput.js
+++ b/src/renderers/dom/fiber/wrappers/ReactDOMFiberInput.js
@@ -209,7 +209,7 @@ var ReactDOMInput = {
// browsers typically do this as necessary, jsdom doesn't.
node.value = '' + value;
}
- } else if (node.value !== value) {
+ } else if (node.value !== '' + value) {
// Cast `value` to a string to ensure the value is set correctly. While
// browsers typically do this as necessary, jsdom doesn't.
node.value = '' + value;
diff --git a/src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js b/src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
index 19a38b9e182f..6c7df548136e 100644
--- a/src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
+++ b/src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
@@ -471,6 +471,46 @@ describe('ReactDOMInput', () => {
expect(nodeValueSetter.mock.calls.length).toBe(1);
});
+ it('should not incur unnecessary DOM mutations for numeric type conversion', () => {
+ var container = document.createElement('div');
+ ReactDOM.render(, container);
+
+ var node = container.firstChild;
+ var nodeValue = '0';
+ var nodeValueSetter = jest.genMockFn();
+ Object.defineProperty(node, 'value', {
+ get: function() {
+ return nodeValue;
+ },
+ set: nodeValueSetter.mockImplementation(function(newValue) {
+ nodeValue = newValue;
+ }),
+ });
+
+ ReactDOM.render(, container);
+ expect(nodeValueSetter.mock.calls.length).toBe(0);
+ });
+
+ it('should not incur unnecessary DOM mutations for the boolean type conversion', () => {
+ var container = document.createElement('div');
+ ReactDOM.render(, container);
+
+ var node = container.firstChild;
+ var nodeValue = 'true';
+ var nodeValueSetter = jest.genMockFn();
+ Object.defineProperty(node, 'value', {
+ get: function() {
+ return nodeValue;
+ },
+ set: nodeValueSetter.mockImplementation(function(newValue) {
+ nodeValue = newValue;
+ }),
+ });
+
+ ReactDOM.render(, container);
+ expect(nodeValueSetter.mock.calls.length).toBe(0);
+ });
+
it('should properly control a value of number `0`', () => {
var stub = ;
stub = ReactTestUtils.renderIntoDocument(stub);
diff --git a/src/renderers/dom/stack/client/wrappers/ReactDOMInput.js b/src/renderers/dom/stack/client/wrappers/ReactDOMInput.js
index b05ca82b352d..a993df0543b7 100644
--- a/src/renderers/dom/stack/client/wrappers/ReactDOMInput.js
+++ b/src/renderers/dom/stack/client/wrappers/ReactDOMInput.js
@@ -201,7 +201,7 @@ var ReactDOMInput = {
// browsers typically do this as necessary, jsdom doesn't.
node.value = '' + value;
}
- } else if (node.value !== value) {
+ } else if (node.value !== '' + value) {
// Cast `value` to a string to ensure the value is set correctly. While
// browsers typically do this as necessary, jsdom doesn't.
node.value = '' + value;