Skip to content

Commit

Permalink
Fix ReactDOMInput and ReactDOMTextarea Race Condition
Browse files Browse the repository at this point in the history
This fixes a race condition if the `onClick` tries to update the input or textarea (e.g. by calling `setState`):

  <input
    onClick={function(event) {
      this.setState({somethingElse: true}); // Triggers an update.
      // event.target.value is now equal to the old value, fail...
      this.props.onChange(event);
    })
  />
  • Loading branch information
jeffmo authored and zpao committed Jul 1, 2013
1 parent f39a0f8 commit 40bebf0
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/dom/components/ReactDOMInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
};
},

shouldComponentUpdate: function() {
// Defer any updates to this component during the `onChange` handler.
return !this._isChanging;
},

getChecked: function() {
return this.props.checked != null ? this.props.checked : this.state.checked;
},
Expand Down Expand Up @@ -91,7 +96,9 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
handleChange: ReactCompositeComponent.autoBind(function(event) {
var returnValue;
if (this.props.onChange) {
this._isChanging = true;
returnValue = this.props.onChange(event);
this._isChanging = false;
}
this.setState({
checked: event.target.checked,
Expand Down
7 changes: 7 additions & 0 deletions src/dom/components/ReactDOMTextarea.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
};
},

shouldComponentUpdate: function() {
// Defer any updates to this component during the `onChange` handler.
return !this._isChanging;
},

getValue: function() {
return this.props.value != null ? this.props.value : this.state.value;
},
Expand Down Expand Up @@ -118,7 +123,9 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
handleChange: ReactCompositeComponent.autoBind(function(event) {
var returnValue;
if (this.props.onChange) {
this._isChanging = true;
returnValue = this.props.onChange(event);
this._isChanging = false;
}
this.setState({value: event.target.value});
return returnValue;
Expand Down

0 comments on commit 40bebf0

Please sign in to comment.