Fix input/textarea `value` of number 0 and `false`
Previously, setting textarea `value` to number 0 is treated as if `value` wasn't set at all (thus the textarea is cleared from 0 to '' upon `onChange`). `false` also renders as `"false"` instead of `""` for both `defaultValue` and `value`, on textarea _and_ input.
Cheng Lou committed
Aug 17, 2013 at 12:16 UTC
cd019871e3b492ad32d9a3ac11973100687b06b7
4 files changed
+55
-6
src/dom/components/ReactDOMInput.js
+8
-5
@@ -50,9 +50,10 @@ var instancesByReactID = {};
50
var ReactDOMInput = ReactCompositeComponent.createClass({
51
52
getInitialState: function() {
53
+ var defaultValue = this.props.defaultValue;
54
return {
55
checked: this.props.defaultChecked || false,
55
- value: this.props.defaultValue != null ? this.props.defaultValue : ''
56
+ value: defaultValue != null && defaultValue !== false ? defaultValue : ''
57
};
58
},
59
@@ -69,9 +70,11 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
70
props.defaultValue = null;
71
props.checked =
72
this.props.checked != null ? this.props.checked : this.state.checked;
72
- // Cast `this.props.value` to a string so equality checks pass.
73
- props.value =
74
- this.props.value != null ? '' + this.props.value : this.state.value;
73
+
74
+ props.value = this.props.value != null && this.props.value !== false
75
+ ? '' + this.props.value
76
+ : this.state.value;
77
+
78
props.onChange = this._handleChange;
79
80
return input(props, this.props.children);
@@ -102,7 +105,7 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
105
DOMPropertyOperations.setValueForProperty(
106
rootNode,
107
'value',
105
- '' + this.props.value || ''
108
+ this.props.value !== false ? '' + this.props.value : ''
109
);
110
}
111
},
src/dom/components/ReactDOMTextarea.js
+1
-1
@@ -117,7 +117,7 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
117
DOMPropertyOperations.setValueForProperty(
118
rootNode,
119
'value',
120
- this.props.value || ''
120
+ this.props.value !== false ? '' + this.props.value : ''
121
);
122
}
123
},
src/dom/components/__tests__/ReactDOMInput-test.js
+23
@@ -45,6 +45,13 @@ describe('ReactDOMInput', function() {
45
expect(node.value).toBe('0');
46
});
47
48
+ it('should display "" for `defaultValue` of `false`', function() {
49
+ var stub = <input type="text" defaultValue={false} />;
50
+ var node = renderTextInput(stub);
51
+
52
+ expect(node.value).toBe('');
53
+ });
54
+
55
it('should display `value` of number 0', function() {
56
var stub = <input type="text" value={0} />;
57
var node = renderTextInput(stub);
@@ -52,6 +59,22 @@ describe('ReactDOMInput', function() {
59
expect(node.value).toBe('0');
60
});
61
62
+ it('should display "" for `value` of `false`', function() {
63
+ var stub = <input type="text" value={false} />;
64
+ var node = renderTextInput(stub);
65
+
66
+ expect(node.value).toBe('');
67
+ });
68
+
69
+ it('should properly control a value of number `0`', function() {
70
+ var stub = <input type="text" value={0} />;
71
+ var node = renderTextInput(stub);
72
+
73
+ node.value = 'giraffe';
74
+ ReactTestUtils.Simulate.input(node);
75
+ expect(node.value).toBe('0');
76
+ });
77
+
78
it('should control radio buttons', function() {
79
var RadioGroup = React.createClass({
80
render: function() {
src/dom/components/__tests__/ReactDOMTextarea-test.js
+23
@@ -58,6 +58,13 @@ describe('ReactDOMTextarea', function() {
58
expect(node.value).toBe('0');
59
});
60
61
+ it('should display "" for `defaultValue` of `false`', function() {
62
+ var stub = <textarea type="text" defaultValue={false} />;
63
+ var node = renderTextarea(stub);
64
+
65
+ expect(node.value).toBe('');
66
+ });
67
+
68
it('should allow setting `value`', function() {
69
var stub = <textarea value="giraffe" />;
70
var node = renderTextarea(stub);
@@ -75,6 +82,22 @@ describe('ReactDOMTextarea', function() {
82
expect(node.value).toBe('0');
83
});
84
85
+ it('should display "" for `value` of `false`', function() {
86
+ var stub = <textarea type="text" value={false} />;
87
+ var node = renderTextarea(stub);
88
+
89
+ expect(node.value).toBe('');
90
+ });
91
+
92
+ it('should properly control a value of number `0`', function() {
93
+ var stub = <textarea value={0} />;
94
+ var node = renderTextarea(stub);
95
+
96
+ node.value = 'giraffe';
97
+ ReactTestUtils.Simulate.input(node);
98
+ expect(node.value).toBe('0');
99
+ });
100
+
101
it('should treat children like `defaultValue`', function() {
102
spyOn(console, 'warn');
103