I am trying to understand the underlying cause for some somewhat \"magical\" behavior I am seeing that I cannot fully explain, and which is not apparent from reading the Rea
This is not exactly an answer, but one possible approach to mitigating the issue. It defines a wrapper for React inputs that manages value updates synchronously via a local state shim; and versions the outgoing values so that only the latest returned from asynchronous processing is ever applied.
It's based on some work by Stephen Sugden (https://github.com/grncdr) which I updated for modern React and improved by versioning the values, which eliminates the race condition.
It's not beautiful :)
http://jsfiddle.net/yrmmbjm1/1/
var AsyncInput = asyncInput('input');
Here is how components need to use it:
var AI = asyncInput('input');
var Test = React.createClass({
// the controlling component must track
// the version
change: function(e, i) {
var v = e.target.value;
setTimeout(function() {
this.setState({v: v, i: i});
}.bind(this), Math.floor(Math.random() * 100 + 50));
},
getInitialState: function() { return {v: ''}; },
render: function() {
{/* and pass it down to the controlled input, yuck */}
return
}
});
React.render( , document.body);
Another version that attempts to make the impact on the controlling component's code less obnoxious is here:
http://jsfiddle.net/yrmmbjm1/4/
That ends up looking like:
var AI = asyncInput('input');
var Test = React.createClass({
// the controlling component must send versionedValues
// back down to the input
change: function(e) {
var v = e.target.value;
var f = e.valueFactory;
setTimeout(function() {
this.setState({v: f(v)});
}.bind(this), Math.floor(Math.random() * 100 + 50));
},
getInitialState: function() { return {v: ''}; },
render: function() {
{/* and pass it down to the controlled input, yuck */}
return
}
});
React.render( , document.body);
¯\_(ツ)_/¯