<main></main>
.btn-reset {
  margin: 10px 0;
  display:block;
}
var initialText = "type something";
var CountedTextModel = Backbone.Model.extend({
  defaults: {
    text: initialText
  },
  revert: function() {
    this.set({text: initialText});
  }
});

var CountedTextView = React.createClass({
  render: function() {
    var text = this.state.text;
    var count = this.state.text.length;
    
    return <div>
      <textarea onChange={this.textChanged} value={text}></textarea>
      <button className="btn-reset" onClick={this.revert}>Revert</button>
        <p>You typed {count} characters in the box</p>
      </div>
  },
  
  getInitialState: function() {
    return this.props.model.toJSON();
  },
  componentDidMount: function() {
    this.props.model.on('change', this.setStateFromModel);
  },
  componentWillUnmount: function() {
    this.props.model.off('change', this.setStateFromModel);
  },
  
  setStateFromModel: function() {
    this.setState(this.props.model.toJSON());
  },
  textChanged: function(e) {
    this.props.model.set({text: e.target.value});
  },  
  revert: function(e) {
    this.props.model.revert();
  }  
});

var model = new CountedTextModel();
React.render(<CountedTextView model={model} />, document.querySelector('main'));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.1/backbone-min.js