@samitouri / QOS-React-2 / commits / cd019871e3

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