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...