|
@@ -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)}
|
|
|
|
+ />);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|