React.js教程:注释不会附加到列表中

时间:2015-03-17 19:03:44

标签: javascript reactjs

我正在做React.js教程,这是我的代码:

//Comment box
var CommentBox = React.createClass({
  loadCommentsFromServer: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      success: function(data) {
        this.setState({data: data});
        console.log('Data has obtained... Refresh state')
      }.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;
    var newComments = comments.concat([comment]);
    this.setState({data: newComments});
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: comment,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        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>
    );
  }
});

//Comment list
var CommentList = React.createClass({
  render: function() {
    var commentNodes = this.props.data.map(function(comment) {
      return (
        <Comment author={comment.author}>
          {comment.text}
        </Comment>
      );
    });
    return (
      <div className="commentList">
        {commentNodes}
      </div>
    );
  }
});

//Comment form
var CommentForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();
    var author = React.findDOMNode(this.refs.author).value.trim();
    var text = React.findDOMNode(this.refs.text).value.trim();
    if (!text || !author) {
      return;
    }
    this.props.onCommentSubmit({author: author, text: text});
    //TODO: send request to the server
    React.findDOMNode(this.refs.author).value = '';
    React.findDOMNode(this.refs.text).value = '';
  },
  render: function() {
    return (
        <form className="commentForm" onSubmit={this.handleSubmit}>
          <input type="text" placeholder="Your name" ref="author" />
          <input type="text" placeholder="Say something..." ref="text" />
          <input type="submit" value="Post" />
        </form>
    );
  }
});

//Comment
var converter = new Showdown.converter();
var Comment = React.createClass({
  render: function() {
    var rawMarkup = converter.makeHtml(this.props.children.toString());
    return (
      <div className="comment panel">
        <h3 className="commentAuthor">
          {this.props.author}
        </h3>
        <span dangerouslySetInnerHTML={{__html: rawMarkup}} />
      </div>
    );
  }
});

React.render(
    <CommentBox url="comments.json" pollInterval={2000} />,
    document.getElementById('example')
);

HTML文件如下所示:

<!DOCTYPE html>
<html>
<head>
  <title>8R</title>
  <meta charset="utf-8">
  <script src="react.js"></script>
  <script src="JSXTransformer.js"></script>
  <script src="jquery-2.1.3.min.js"></script>
  <script src="showdown.min.js"></script>
</head>
<body>

<div id="example"></div>

<script type="text/jsx" src="app.js"></script>
</body>
</html>

我有comments.json文件和评论:

[
  {"author": "Pete Hunt", "text": "This is one comment"},
  {"author": "Jordan Walker", "text": "This is *another* comment"},
  {"author": "Mary Jane", "text": "My comment is the best comment"},
  {"author": "Peter Parker", "text": "Have you called spider-man?"}
]

这些评论出现在列表中,但是当我在评论表单中输入我自己的评论并提交时,它不会出现在列表中。在Chrome中,它只会闪烁一秒钟而消失,这就是全部。我试图在Webstorm的localhost和MAMP服务器上做到这一点,并且我得到了相同的结果。 有什么问题?

3 个答案:

答案 0 :(得分:2)

如果有其他人来到这里并希望使用他们已经设置的自己的PHP服务器(而不是使用反应服务器脚本),您可以这样做:

// in your commentsBox class declaration
handleCommentSubmit: function(comment) {

   console.log(comment);
   //console.log(this.props.url);

   var comments = this.state.data;
   var newComments = comments.concat([comment]);

   this.setState({data: newComments});

   $.ajax({
        url: '../update_json_manager.php', // declare your own file to post to
        dataType: 'json',
        type: 'POST',
        data: comment,
        success: function(data) {
          this.setState({data: data});
          console.log(data);
        }.bind(this),
        error: function(xhr, status, err) {
          console.error(xhr, status, err.toString());
        }.bind(this)
   });

},

然后你可以收到帖子并像这样更新你的json文件(在update_json_manager.php所在的文件中名为comments.json的文件中:

<?php
$comments = file_get_contents('comments.json');

$commentsDecoded = json_decode($comments, true);
$commentsDecoded[] = ['author'  => $_POST['author'],
                      'text'    => $_POST['text']];

$comments = json_encode($commentsDecoded, JSON_PRETTY_PRINT);
file_put_contents('comments.json', $comments);
?>

答案 1 :(得分:1)

您可以从Github下载的zip,您提到的React示例包括各种语言的服务器脚本,这些脚本将处理示例中的JSON数据更新。

因此,如果您下载并使用其中一个服务器脚本在本地运行示例,您将看到您的代码可以正常工作。 ajax调用会将您的注释数据发送到指定的url,服务器脚本将负责更新JSON注释文件。

HTH

答案 2 :(得分:1)

我认为您可以做的是在componentDidMount中注释掉setInterval函数。

componentDidMount: function() {
    this.loadCommentsFromServer();
    //setInterval(this.loadCommentsFromServer, this.props.pollInterval);
},

如果您查看comments.json,您会发现您的评论未附加在那里。因此,每次获取时,您的列表将返回到原始状态。