@samitouri / QOS-React-2 / commits / 0d20dcf910

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);