React with Cursors

React with Cursors

by marcfawzi

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>

<div id="root"/>

JavaScript 1.7

let {Cursor} = ReactCursor;

class App extends React.Component {
  render () {
  console.log('App')
	  return <div>
      <h1>App State:</h1>
      <p><code>{JSON.stringify(this.props.cur.value(), undefined, 2)}</code></p>
      <BeanCounters cur={this.props.cur} />
		</div>;
  }
}

class BeanCounters extends React.Component {

  render () {

		console.log('BeanCounters')
  
    let cur1 = this.props.cur.refine('accounting').refine('beans');
    let cur2 = this.props.cur.refine('accounting').refine('beanCounters');        
    let cur3 = this.props.cur.refine('staff')
     
     
    let clickers =_.map(cur1.value(), (count, i) => {
      return <Clicker key={i} cur1={cur1.refine(i)} cur2={cur2.refine(i)} cur3={cur3.refine(cur2.refine(i).value())}/>;
    });
    return <div>
      <h2>BeanCounters State:</h2>
      <p><code>{JSON.stringify(cur1.value(), undefined, 2)}</code></p>
      {clickers}
    </div>;
  }
}


class Clicker extends React.Component {

  shouldComponentUpdate(nextProps) {
  
  return    (this.props.cur1 !== nextProps.cur1 ||
     				this.props.cur2 !== nextProps.cur2 ||
            this.props.cur3 !== nextProps.cur3)
  }
  
  render () {
    
    console.log('Cllicker')
 
 		let cur1 = this.props.cur1;
    let cur2 = this.props.cur2;
    let cur3 = this.props.cur3;
    
    return (
      <div>  
        <button onClick={() => cur1.swap(v => v+1)}>+1</button>
        &nbsp;
        <span>{cur2.value()}&nbsp;<code>{JSON.stringify(cur1.value(), undefined, 2)}, {cur3.value()}</code></span>
      </div>
    );
  }
}

class AppStateContainer extends React.Component {
  constructor (props) {
    super(props);
    
    // conceptually, an atom is a *mutable* reference to an immutable value. Cursors provide immutable getters and setters to values within the atom selected by a path. Since those values are immutable, cursors   
    // can be used for O(1) rendering optimization via shouldComponentUpdate. 
    // The cursor is constructed in render()...