Skip to content

Commit 81a9a75

Browse files
committed
Only assign defaultValue if it has changed.
1 parent c78464f commit 81a9a75

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

src/renderers/dom/client/wrappers/ReactDOMInput.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,11 @@ var ReactDOMInput = {
213213
}
214214
} else {
215215
if (props.value == null && props.defaultValue != null) {
216-
node.defaultValue = '' + props.defaultValue;
216+
// Assigning defaultValue causes side-effects on value, which can cause
217+
// unexpected value changes and selections skipping. A quick check avoids this
218+
if (node.defaultValue !== '' + props.defaultValue) {
219+
node.defaultValue = '' + props.defaultValue;
220+
}
217221
}
218222
if (props.checked == null && props.defaultChecked != null) {
219223
node.defaultChecked = !!props.defaultChecked;

src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js

+22
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,28 @@ describe('ReactDOMInput', () => {
5151
expect(node.value).toBe('0');
5252
});
5353

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+
5476
it('should display "true" for `defaultValue` of `true`', () => {
5577
var stub = <input type="text" defaultValue={true} />;
5678
stub = ReactTestUtils.renderIntoDocument(stub);

0 commit comments

Comments
 (0)