@samitouri / QOS-React-2 / commits / eee3980749
Fork 0

The library for web and native user interfaces.

Stringify `value` in ReactDOMInput / ChangeEventPlugin

This fixes two bugs related to string-casting in React: # Setting `<input value={0} />` would use an empty `value` because `0` is falsey. # Using `onChange` and `setState` with non-strings could lead to an infinite loop. The latter is possible with controlled inputs when: - User changes input value. - `onpropertychange` fires. - `ChangeEventPlugin` dispatches `onChange`. - A handler responds via `this.setState` with a non-string value (e.g. a number). - The input re-renders and re-sets `value`. - The new `value` is not a string, but the current `value` (read from the element) is cast to a string automatically by the browser. - This triggers another `onpropertychange`. - `ChangeEventPlugin` dispatches another `onChange`. - ...

Tim Yung committed Jul 12, 2013 at 15:40 UTC eee3980749c13f8f80ed7cf839b325a2d56ffad4
2 files changed +8 -4
src/dom/components/ReactDOMInput.js
+5 -2
@@ -62,7 +62,8 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
62 },
63
64 getValue: function() {
65 - return this.props.value != null ? this.props.value : this.state.value;
65 + // Cast `this.props.value` to a string so equality checks pass.
66 + return this.props.value != null ? '' + this.props.value : this.state.value;
67 },
68
69 render: function() {
@@ -85,10 +86,12 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
86 );
87 }
88 if (this.props.value != null) {
89 + // Cast `this.props.value` to a string so falsey values that cast to
90 + // truthy strings are not ignored.
91 DOMPropertyOperations.setValueForProperty(
92 rootNode,
93 'value',
91 - this.props.value || ''
94 + '' + this.props.value || ''
95 );
96 }
97 },
src/eventPlugins/ChangeEventPlugin.js
+3 -2
@@ -169,7 +169,8 @@ var newValueProp = {
169 return activeElementValueProp.get.call(this);
170 },
171 set: function(val) {
172 - activeElementValue = val;
172 + // Cast to a string so we can do equality checks.
173 + activeElementValue = '' + val;
174 activeElementValueProp.set.call(this, val);
175 }
176 };
@@ -231,7 +232,7 @@ function handlePropertyChange(nativeEvent) {
232 /**
233 * If a `change` event should be fired, returns the target's ID.
234 */
234 -function getTargetIDForInputEvent(
235 +function getTargetIDForInputEvent(
236 topLevelType,
237 topLevelTarget,
238 topLevelTargetID) {