|  | @@ -22,21 +22,37 @@ Lifecycle methods:
 | 
											
												
													
														|  |  - fetch initial data from cWM, start a refresh poll loop from cDM, stop loop from cWU
 |  |  - fetch initial data from cWM, start a refresh poll loop from cDM, stop loop from cWU
 | 
											
												
													
														|  |   - https://facebook.github.io/react/docs/react-component.html
 |  |   - https://facebook.github.io/react/docs/react-component.html
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +One-way control / data flow: control flows from higher level components down to
 | 
											
												
													
														|  | 
 |  | +child components, forcing changes to happen reactively.
 | 
											
												
													
														|  | 
 |  | +- example 1: CommentBox passes _deleteComment as callback to its Comment child
 | 
											
												
													
														|  | 
 |  | +- example 2: CommentBox passes _addComment as callback to its CommentForm child
 | 
											
												
													
														|  | 
 |  | + - both are passed as props.
 | 
											
												
													
														|  | 
 |  | +- example 3: CommentBox passes author and body props to Comment (in previous versions)
 | 
											
												
													
														|  | 
 |  | +When a child wants to send data back to the parent it does it through a callback
 | 
											
												
													
														|  | 
 |  | +provided by the parent as a prop.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  JSX:
 |  |  JSX:
 | 
											
												
													
														|  |  - "className", not "class"
 |  |  - "className", not "class"
 | 
											
												
													
														|  |  - knows how to render an array of JSX elements, not just one.
 |  |  - knows how to render an array of JSX elements, not just one.
 | 
											
												
													
														|  |   */
 |  |   */
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  class Comment extends React.Component {
 |  |  class Comment extends React.Component {
 | 
											
												
													
														|  | 
 |  | +  _handleDelete(event) {
 | 
											
												
													
														|  | 
 |  | +    event.preventDefault();
 | 
											
												
													
														|  | 
 |  | +    if (confirm("Are you sure?")) {
 | 
											
												
													
														|  | 
 |  | +      this.props.onDelete(this.props.comment);
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |    render() {
 |  |    render() {
 | 
											
												
													
														|  |      return (
 |  |      return (
 | 
											
												
													
														|  |        <div className="comment">
 |  |        <div className="comment">
 | 
											
												
													
														|  | -        <p className="comment-header">{this.props.author}</p>
 |  | 
 | 
											
												
													
														|  | 
 |  | +        <p className="comment-header">{this.props.comment.author}</p>
 | 
											
												
													
														|  |          <p className="comment-body">
 |  |          <p className="comment-body">
 | 
											
												
													
														|  | -          {this.props.body}
 |  | 
 | 
											
												
													
														|  | 
 |  | +          {this.props.comment.body}
 | 
											
												
													
														|  |          </p>
 |  |          </p>
 | 
											
												
													
														|  |          <div className="comment-footer">
 |  |          <div className="comment-footer">
 | 
											
												
													
														|  | -          <a href="#" className="comment-footer-delete">
 |  | 
 | 
											
												
													
														|  | 
 |  | +          <a href="#" className="comment-footer-delete" onClick={this._handleDelete.bind(this)}>
 | 
											
												
													
														|  |              Delete comment
 |  |              Delete comment
 | 
											
												
													
														|  |            </a>
 |  |            </a>
 | 
											
												
													
														|  |          </div>
 |  |          </div>
 | 
											
										
											
												
													
														|  | @@ -86,19 +102,32 @@ class CommentBox extends React.Component {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |    _addComment(author, body) {
 |  |    _addComment(author, body) {
 | 
											
												
													
														|  |      const comment = {
 |  |      const comment = {
 | 
											
												
													
														|  | -      id: this.state.comments.length + 1,
 |  | 
 | 
											
												
													
														|  |        author,
 |  |        author,
 | 
											
												
													
														|  |        body
 |  |        body
 | 
											
												
													
														|  |      };
 |  |      };
 | 
											
												
													
														|  | -    // concat(), not push(): push() mutates the data, concat doesn't.
 |  | 
 | 
											
												
													
														|  | -    // By allocating a new reference, for comments, React detects the change fast.
 |  | 
 | 
											
												
													
														|  | -    this.setState({comments: this.state.comments.concat([comment])});
 |  | 
 | 
											
												
													
														|  | 
 |  | +    jQuery.post("api/comments", {comment})
 | 
											
												
													
														|  | 
 |  | +      .success(newComment => {
 | 
											
												
													
														|  | 
 |  | +        // concat(), not push(): push() mutates the data, concat doesn't.
 | 
											
												
													
														|  | 
 |  | +        // By allocating a new reference, for comments, React detects the change fast.
 | 
											
												
													
														|  | 
 |  | +        this.setState({comments: this.state.comments.concat([newComment])});
 | 
											
												
													
														|  | 
 |  | +      });
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  _deleteComment(comment) {
 | 
											
												
													
														|  | 
 |  | +    jQuery.ajax({
 | 
											
												
													
														|  | 
 |  | +      method: "DELETE",
 | 
											
												
													
														|  | 
 |  | +      url: `api/comments/${comment.id}`
 | 
											
												
													
														|  | 
 |  | +    });
 | 
											
												
													
														|  | 
 |  | +    const comments = [...this.state.comments];
 | 
											
												
													
														|  | 
 |  | +    const commentIndex = comments.indexOf(comment);
 | 
											
												
													
														|  | 
 |  | +    comments.splice(commentIndex, 1);
 | 
											
												
													
														|  | 
 |  | +    this.setState({comments});
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |    _fetchComments() {
 |  |    _fetchComments() {
 | 
											
												
													
														|  |      jQuery.ajax({
 |  |      jQuery.ajax({
 | 
											
												
													
														|  |        method: "GET",
 |  |        method: "GET",
 | 
											
												
													
														|  | -      url: "/static/comments.json",
 |  | 
 | 
											
												
													
														|  | 
 |  | +      url: "/api/comments",
 | 
											
												
													
														|  |        // Arrow function: keep "this" binding to the class instance.
 |  |        // Arrow function: keep "this" binding to the class instance.
 | 
											
												
													
														|  |        success: (comments) => {
 |  |        success: (comments) => {
 | 
											
												
													
														|  |          this.setState({comments});
 |  |          this.setState({comments});
 | 
											
										
											
												
													
														|  | @@ -109,9 +138,10 @@ class CommentBox extends React.Component {
 | 
											
												
													
														|  |    _getComments() {
 |  |    _getComments() {
 | 
											
												
													
														|  |      return this.state.comments.map((comment) => {
 |  |      return this.state.comments.map((comment) => {
 | 
											
												
													
														|  |        return (<Comment
 |  |        return (<Comment
 | 
											
												
													
														|  | -        author={comment.author}
 |  | 
 | 
											
												
													
														|  | -        body={comment.body}
 |  | 
 | 
											
												
													
														|  | -        key={comment.id} />);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        key={comment.id}
 | 
											
												
													
														|  | 
 |  | +        comment={comment}
 | 
											
												
													
														|  | 
 |  | +        onDelete={this._deleteComment.bind(this)}
 | 
											
												
													
														|  | 
 |  | +      />);
 | 
											
												
													
														|  |      });
 |  |      });
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 |