Fix uncontrolled input decimal point "chopping" on number inputs, and validation warnings on email inputs (#7750)
* Only assign defaultValue if it has changed. * Improve comment about reason for defaultValue conditional assignment
Nathan Hunzaker committed
Oct 13, 2016 at 09:20 UTC
0d20dcf9108811f632bfeb76a6bd3bf05d11865b
2 files changed
+33
-1
src/renderers/dom/client/wrappers/ReactDOMInput.js
+11
-1
@@ -213,7 +213,17 @@ var ReactDOMInput = {
213
}
214
} else {
215
if (props.value == null && props.defaultValue != null) {
216
- node.defaultValue = '' + props.defaultValue;
216
+ // In Chrome, assigning defaultValue to certain input types triggers input validation.
217
+ // For number inputs, the display value loses trailing decimal points. For email inputs,
218
+ // Chrome raises "The specified value <x> is not a valid email address".
219
+ //
220
+ // Here we check to see if the defaultValue has actually changed, avoiding these problems
221
+ // when the user is inputting text
222
+ //
223
+ // https://github.com/facebook/react/issues/7253
224
+ if (node.defaultValue !== '' + props.defaultValue) {
225
+ node.defaultValue = '' + props.defaultValue;
226
+ }
227
}
228
if (props.checked == null && props.defaultChecked != null) {
229
node.defaultChecked = !!props.defaultChecked;
src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js
+22
@@ -51,6 +51,28 @@ describe('ReactDOMInput', () => {
51
expect(node.value).toBe('0');
52
});
53
54
+ it('only assigns defaultValue if it changes', () => {
55
+ class Test extends React.Component {
56
+ render() {
57
+ return (<input defaultValue="0" />);
58
+ }
59
+ }
60
+
61
+ var component = ReactTestUtils.renderIntoDocument(<Test />);
62
+ var node = ReactDOM.findDOMNode(component);
63
+
64
+ Object.defineProperty(node, 'defaultValue', {
65
+ get() {
66
+ return '0';
67
+ },
68
+ set(value) {
69
+ throw new Error(`defaultValue was assigned ${value}, but it did not change!`);
70
+ },
71
+ });
72
+
73
+ component.forceUpdate();
74
+ });
75
+
76
it('should display "true" for `defaultValue` of `true`', () => {
77
var stub = <input type="text" defaultValue={true} />;
78
stub = ReactTestUtils.renderIntoDocument(stub);