example.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /**
  2. * This file provided by Facebook is for non-commercial testing and evaluation
  3. * purposes only. Facebook reserves all rights not expressly granted.
  4. *
  5. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  6. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  7. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  8. * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  9. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  10. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  11. */
  12. var Comment = React.createClass({
  13. rawMarkup: function() {
  14. var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
  15. return { __html: rawMarkup };
  16. },
  17. render: function() {
  18. return (
  19. <div className="comment">
  20. <h2 className="commentAuthor">
  21. {this.props.author}
  22. </h2>
  23. <span dangerouslySetInnerHTML={this.rawMarkup()} />
  24. </div>
  25. );
  26. }
  27. });
  28. var CommentBox = React.createClass({
  29. loadCommentsFromServer: function() {
  30. $.ajax({
  31. url: this.props.url,
  32. dataType: 'json',
  33. cache: false,
  34. success: function(data) {
  35. this.setState({data: data});
  36. }.bind(this),
  37. error: function(xhr, status, err) {
  38. console.error(this.props.url, status, err.toString());
  39. }.bind(this)
  40. });
  41. },
  42. handleCommentSubmit: function(comment) {
  43. var comments = this.state.data;
  44. // Optimistically set an id on the new comment. It will be replaced by an
  45. // id generated by the server. In a production application you would likely
  46. // not use Date.now() for this and would have a more robust system in place.
  47. comment.id = Date.now();
  48. var newComments = comments.concat([comment]);
  49. this.setState({data: newComments});
  50. $.ajax({
  51. url: this.props.url,
  52. dataType: 'json',
  53. type: 'POST',
  54. data: comment,
  55. success: function(data) {
  56. this.setState({data: data});
  57. }.bind(this),
  58. error: function(xhr, status, err) {
  59. this.setState({data: comments});
  60. console.error(this.props.url, status, err.toString());
  61. }.bind(this)
  62. });
  63. },
  64. getInitialState: function() {
  65. return {data: []};
  66. },
  67. componentDidMount: function() {
  68. this.loadCommentsFromServer();
  69. setInterval(this.loadCommentsFromServer, this.props.pollInterval);
  70. },
  71. render: function() {
  72. return (
  73. <div className="commentBox">
  74. <h1>Comments</h1>
  75. <CommentList data={this.state.data} />
  76. <CommentForm onCommentSubmit={this.handleCommentSubmit} />
  77. </div>
  78. );
  79. }
  80. });
  81. var CommentList = React.createClass({
  82. render: function() {
  83. var commentNodes = this.props.data.map(function(comment) {
  84. return (
  85. <Comment author={comment.author} key={comment.id}>
  86. {comment.text}
  87. </Comment>
  88. );
  89. });
  90. return (
  91. <div className="commentList">
  92. {commentNodes}
  93. </div>
  94. );
  95. }
  96. });
  97. var CommentForm = React.createClass({
  98. getInitialState: function() {
  99. return {author: '', text: ''};
  100. },
  101. handleAuthorChange: function(e) {
  102. this.setState({author: e.target.value});
  103. },
  104. handleTextChange: function(e) {
  105. this.setState({text: e.target.value});
  106. },
  107. handleSubmit: function(e) {
  108. e.preventDefault();
  109. var author = this.state.author.trim();
  110. var text = this.state.text.trim();
  111. if (!text || !author) {
  112. return;
  113. }
  114. this.props.onCommentSubmit({author: author, text: text});
  115. this.setState({author: '', text: ''});
  116. },
  117. render: function() {
  118. return (
  119. <form className="commentForm" onSubmit={this.handleSubmit}>
  120. <input
  121. type="text"
  122. placeholder="Your name"
  123. value={this.state.author}
  124. onChange={this.handleAuthorChange}
  125. />
  126. <input
  127. type="text"
  128. placeholder="Say something..."
  129. value={this.state.text}
  130. onChange={this.handleTextChange}
  131. />
  132. <input type="submit" value="Post" />
  133. </form>
  134. );
  135. }
  136. });
  137. ReactDOM.render(
  138. <CommentBox url="/api/comments" pollInterval={2000} />,
  139. document.getElementById('content')
  140. );