JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://fb.me/react-with-addons-0.12.0.js"></script>
<script src="http://fb.me/JSXTransformer-0.12.0.js"></script>
<script src="http://fb.me/react-js-fiddle-integration.js"></script>
JavaScript 1.7
function versionedValue(value, version) {
return {value: value, version: version};
}
function asyncInput (ctor) {
// close over an event counter
var i = 0;
function incrementAndVersion(value) {
return versionedValue(value, i++);
}
return React.createClass({
getInitialState: function () {
return {value: incrementAndVersion(this.props.value)}
},
onChange: function (e) {
var handler = this.props.onChange
if (handler) {
// handlers must adapt to a new protocol, identifying
// each state change with a version
var newValue = incrementAndVersion(e.target.value);
e.valueFactory = function(value) {
return {value: value, version: newValue.version};
};
handler(e)
this.setState({value: newValue});
}
},
componentWillReceiveProps: function (newProps) {
// handle initial case of unversioned value:
if (newProps.value.version === undefined) {
this.setState({value: versionedValue(newProps.value, i)});
}
// otherwise, only accept the latest value from props
else if (newProps.value.version == this.state.value.version) {
this.setState({value: newProps.value})
}
},
render: function () {
return React.createElement(
ctor,
React.__spread({}, this.props, {
value: this.state.value.value,
onChange: this.onChange
}),
this.props.children
)
}
})
}
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...