Skip to content

Commit a65e25f

Browse files
nhunzakergaearon
authored andcommitted
Eliminate unnecessary numeric equality checks (#11751)
* Eliminate unnecessary numeric equality checks This commit changes the way numeric equality for number inputs works such that it compares against `input.valueAsNumber`. This eliminates quite a bit of branching around numeric equality. * There is no need to compare valueAsNumber * Add test cases for empty string to 0. * Avoid implicit boolean JSX props * Split up numeric equality test to isolate eslint disable command * Fix typo in ReactDOMInput test
1 parent d843cfe commit a65e25f

File tree

2 files changed

+58
-10
lines changed

2 files changed

+58
-10
lines changed

packages/react-dom/src/__tests__/ReactDOMInput-test.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,23 @@ describe('ReactDOMInput', () => {
248248
}
249249
});
250250

251+
it('performs a state change from "" to 0', () => {
252+
class Stub extends React.Component {
253+
state = {
254+
value: '',
255+
};
256+
render() {
257+
return <input type="number" value={this.state.value} readOnly={true} />;
258+
}
259+
}
260+
261+
var stub = ReactTestUtils.renderIntoDocument(<Stub />);
262+
var node = ReactDOM.findDOMNode(stub);
263+
stub.setState({value: 0});
264+
265+
expect(node.value).toEqual('0');
266+
});
267+
251268
it('distinguishes precision for extra zeroes in string number values', () => {
252269
spyOnDev(console, 'error');
253270
class Stub extends React.Component {
@@ -595,6 +612,7 @@ describe('ReactDOMInput', () => {
595612
var node = container.firstChild;
596613

597614
expect(node.value).toBe('0');
615+
expect(node.defaultValue).toBe('0');
598616
});
599617

600618
it('should properly transition from 0 to an empty value', function() {
@@ -606,6 +624,43 @@ describe('ReactDOMInput', () => {
606624
var node = container.firstChild;
607625

608626
expect(node.value).toBe('');
627+
expect(node.defaultValue).toBe('');
628+
});
629+
630+
it('should properly transition a text input from 0 to an empty 0.0', function() {
631+
var container = document.createElement('div');
632+
633+
ReactDOM.render(<input type="text" value={0} />, container);
634+
ReactDOM.render(<input type="text" value="0.0" />, container);
635+
636+
var node = container.firstChild;
637+
638+
expect(node.value).toBe('0.0');
639+
expect(node.defaultValue).toBe('0.0');
640+
});
641+
642+
it('should properly transition a number input from "" to 0', function() {
643+
var container = document.createElement('div');
644+
645+
ReactDOM.render(<input type="number" value="" />, container);
646+
ReactDOM.render(<input type="number" value={0} />, container);
647+
648+
var node = container.firstChild;
649+
650+
expect(node.value).toBe('0');
651+
expect(node.defaultValue).toBe('0');
652+
});
653+
654+
it('should properly transition a number input from "" to "0"', function() {
655+
var container = document.createElement('div');
656+
657+
ReactDOM.render(<input type="number" value="" />, container);
658+
ReactDOM.render(<input type="number" value="0" />, container);
659+
660+
var node = container.firstChild;
661+
662+
expect(node.value).toBe('0');
663+
expect(node.defaultValue).toBe('0');
609664
});
610665

611666
it('should have the correct target value', () => {

packages/react-dom/src/client/ReactDOMFiberInput.js

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,18 +181,11 @@ export function updateWrapper(element: Element, props: Object) {
181181
var value = getSafeValue(props.value);
182182

183183
if (value != null) {
184-
if (value === 0 && node.value === '') {
185-
node.value = '0';
186-
// Note: IE9 reports a number inputs as 'text', so check props instead.
187-
} else if (props.type === 'number') {
188-
// Simulate `input.valueAsNumber`. IE9 does not support it
189-
var valueAsNumber = parseFloat(node.value) || 0;
190-
184+
if (props.type === 'number') {
191185
if (
186+
(value === 0 && node.value === '') ||
192187
// eslint-disable-next-line
193-
value != valueAsNumber ||
194-
// eslint-disable-next-line
195-
(value == valueAsNumber && node.value != value)
188+
node.value != value
196189
) {
197190
node.value = '' + value;
198191
}

0 commit comments

Comments
 (0)