comments.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. Good practices:
  3. - name CSS classNamees like the associated component
  4. - prefix non-React method names by an "_"
  5. - pass a "key" attribute to elements in a loop
  6. State
  7. - direct reads, write through setState()
  8. - declare initial state in constructo()
  9. JSX:
  10. - "className", not "class"
  11. - knows how to render an array of JSX elements, not just one.
  12. */
  13. const commentList = [
  14. { id: 1, author: "Morgan McCircuit", body: "great picture!" },
  15. { id: 2, author: "Bending Bender", body: "Excellent stuff" }
  16. ];
  17. class Comment extends React.Component {
  18. render() {
  19. return (
  20. <div className="comment">
  21. <p className="comment-header">{this.props.author}</p>
  22. <p className="comment-body">
  23. {this.props.body}
  24. </p>
  25. <div className="comment-footer">
  26. <a href="#" className="comment-footer-delete">
  27. Delete comment
  28. </a>
  29. </div>
  30. </div>
  31. );
  32. }
  33. }
  34. class CommentBox extends React.Component {
  35. constructor() {
  36. super();
  37. this.state = {
  38. showComments: false
  39. };
  40. }
  41. _getComments() {
  42. return commentList.map((comment) => {
  43. return (<Comment
  44. author={comment.author}
  45. body={comment.body}
  46. key={comment.id} />);
  47. });
  48. }
  49. _getCommentsTitle(commentCount) {
  50. if (commentCount === 0) {
  51. return "No comments yet";
  52. } else if (commentCount === 1) {
  53. return "1 comment";
  54. }
  55. return `${commentCount} comments`;
  56. }
  57. _handleClick() {
  58. this.setState({
  59. showComments: !this.state.showComments
  60. });
  61. }
  62. render() {
  63. const comments = this._getComments();
  64. let buttonText = "Show comments";
  65. let commentNodes;
  66. if (this.state.showComments) {
  67. commentNodes = <div className="comment-list">{comments}</div>;
  68. buttonText = "Hide comments";
  69. }
  70. return (
  71. <div className="comment-box">
  72. <button onClick={this._handleClick.bind(this)}>{buttonText}</button>
  73. <h4 className="comment-count">{this._getCommentsTitle(comments.length)}</h4>
  74. {commentNodes}
  75. </div>
  76. );
  77. }
  78. }
  79. ReactDOM.render(
  80. <CommentBox />, document.getElementById('comments-app')
  81. );