blairanderson
3/16/2016 - 12:07 AM

learn-react

learn-react

var CommentList = React.createClass({
  propTypes: {
    data: React.PropTypes.array.isRequired
  },
  getDefaultProps: function(){
    return {
      data: []
    }
  },
  renderComment: function(comment){
    // the 'key' is required for array items! 
    // it lets react know when items are removed and added to the list
    // should not use array index for the key because the indexes may stay while items are re-ordered/removed
    <li key={comment.id}>
      <span>{comment.body}</span>
    </li>
  },
  render: function(){
    <ul>
      {this.props.data.map(this.renderComment)}
    </ul>
  }
})

var CommentBox = React.createClass({
  loadCommentsFromServer: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  handleCommentSubmit: function(comment) {
    var comments = this.state.data;
    // Optimistically set an id on the new comment. It will be replaced by an
    // id generated by the server. In a production application you would likely
    // not use Date.now() for this and would have a more robust system in place.
    comment.id = Date.now();
    var newComments = comments.concat([comment]);
    // we set our expected new state
    // after the server responds we can reset the state
    this.setState({data: newComments});
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: comment,
      success: function(data) {
        // on success, we set the data from the server because it is the source of truth!
        this.setState({data: data, error: false});
      }.bind(this),
      error: function(xhr, status, err) {
        // on error, we put the state back to where it was before.
        // can also show an alert because we have an error
        this.setState({data: comments, error: status});
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  getInitialState: function() {
    return {data: []};
  },
  componentDidMount: function() {
    this.loadCommentsFromServer();
    setInterval(this.loadCommentsFromServer, this.props.pollInterval);
  },
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList data={this.state.data} />
        <CommentForm onCommentSubmit={this.handleCommentSubmit} />
      </div>
    );
  }
});