CowChat

HTML

<script src="https://unpkg.com/[email protected]/dist/react.js"></script>
<script src="https://unpkg.com/[email protected]/dist/react-dom.js"></script>
<div id='chat'>

</div>

Babel + JSX

var data = [
  {line: "I <3 chatik"}
];
var Chat = React.createClass({
  getInitialState: function() {
    return {data: [{id: 0, line: "Moo!"}], counter: 10};
  },
  componentDidMount: function() {
    this.setState({data: this.state.data.concat(data)});
  },
  handleChatSubmit: function(chat) {
    chat.id = this.state.counter;
    this.setState({counter: ++this.state.counter});
    this.setState({data: this.state.data.concat(chat)});
  },
  render: function() {
    var lines = this.state.data.map(function(line) {
      return (
        <ChatLine line={line.line} key={line.line} />
      );
    });
    return (
      <div className="Chat">
        {lines}
        <ChatForm onChatSubmit={this.handleChatSubmit} />
      </div>
    );
  }
});
var ChatLine = React.createClass({
  render: function() {
    return (
      <div className="ChatLine">
        {this.props.line}
      </div>
    );
  }
});
var ChatForm = React.createClass({
  getInitialState: function() {
    return { text: ''};
  },
  handleTextChange: function(e) {
    this.setState({text: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    var text = this.state.text.trim();
    if (!text) {
      return;
    }
    this.props.onChatSubmit({line: text});
    this.setState({text: ''});
  },
  render: function() {
    return (
      <form className="chatForm" onSubmit={this.handleSubmit}>
        <input
          type="text"
          placeholder="Say something..."
          value={this.state.text}
          onChange={this.handleTextChange}
        />
        <input type="submit" value="Post" />
      </form>
    );
  }
});
ReactDOM.render(
  <Chat />,
  document.getElementById('chat')
);