cursor jump bug with js-atom and react-cursor

by Dustin Getz

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script>
<script src="https://fb.me/react-with-addons-0.14.6.js"></script>
<script src="https://fb.me/react-dom-0.14.6.js"></script>
<script src="https://rawgit.com/lodash/lodash/3.10.1/lodash.js"></script>
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>
<script src="https://rawgit.com/dustingetz/react-cursor/b056b7e937ec903f32c3f42af33f00e4edbac31c/dist/react-cursor.js"></script>
<script src="https://rawgit.com/cjohansen/js-atom/master/atom-browser.js"></script>

<div id="root"/>

JavaScript 1.7

let {Cursor} = ReactCursor;

class App extends React.Component {
  render () { 
    return <div>
      <textarea
        autofocus 
        value={this.props.cur.refine('text').value()} 
        onChange={this.change.bind(this)}
        onKeyDown={this.onComposeKeyDown.bind(this)}/>
      <pre>{JSON.stringify(this.props.cur.value(), null, 2)}</pre>
		</div>;
  }

  change (e) { 
    let val = e.target.value;
    this.props.cur.refine('text').set(val);
  }

  onComposeKeyDown (e) {
    var KC_ENTER = 13;
    if (e.keyCode === KC_ENTER && !e.shiftKey) {
      var messageText = this.props.cur.refine('text').value();
      console.log(`Sending message: ${messageText}`);
      e.preventDefault();
    }
  }
}


let store = atom.createAtom({ text: 'I am here' })

let reactDomRender = () => {
  let cur = Cursor.build(store.deref(), store.swap);
  ReactDOM.render(<App cur={cur} />, document.getElementById('root'));
};

// ReactDOM.render sometimes queues a render and sometimes causes an immediate render.
// I believe if invoked in a managed dom callback context, the render is queued for later, but
// if invoked in an ajax callback context, the render is immediate in this stack frame, which we never want.
let queueRender = () => {
  _.defer(reactDomRender);
  //reactDomRender();
}

store.addWatch('react-renderer', queueRender);
queueRender('react-renderer', store, undefined, store.deref());
alert(document.cookie)