mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
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`.
- ...
This commit is contained in:
committed by
Paul O’Shannessy
parent
cf83fbe397
commit
eee3980749
@@ -62,7 +62,8 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
|
||||
},
|
||||
|
||||
getValue: function() {
|
||||
return this.props.value != null ? this.props.value : this.state.value;
|
||||
// Cast `this.props.value` to a string so equality checks pass.
|
||||
return this.props.value != null ? '' + this.props.value : this.state.value;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
@@ -85,10 +86,12 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
|
||||
);
|
||||
}
|
||||
if (this.props.value != null) {
|
||||
// Cast `this.props.value` to a string so falsey values that cast to
|
||||
// truthy strings are not ignored.
|
||||
DOMPropertyOperations.setValueForProperty(
|
||||
rootNode,
|
||||
'value',
|
||||
this.props.value || ''
|
||||
'' + this.props.value || ''
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -169,7 +169,8 @@ var newValueProp = {
|
||||
return activeElementValueProp.get.call(this);
|
||||
},
|
||||
set: function(val) {
|
||||
activeElementValue = val;
|
||||
// Cast to a string so we can do equality checks.
|
||||
activeElementValue = '' + val;
|
||||
activeElementValueProp.set.call(this, val);
|
||||
}
|
||||
};
|
||||
@@ -231,7 +232,7 @@ function handlePropertyChange(nativeEvent) {
|
||||
/**
|
||||
* If a `change` event should be fired, returns the target's ID.
|
||||
*/
|
||||
function getTargetIDForInputEvent(
|
||||
function getTargetIDForInputEvent(
|
||||
topLevelType,
|
||||
topLevelTarget,
|
||||
topLevelTargetID) {
|
||||
|
||||
Reference in New Issue
Block a user