React.js 教程:评论不附加在列表中

React.js tutorial: comments don't append in the list

我正在做 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 的本地主机和 MAMP 服务器上执行此操作,但得到了相同的结果。 有什么问题?

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

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

HTH

我想你可以做的是在你的componentDidMount中注释掉setInterval函数。

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

如果您检查 comments.json,您会发现您的评论没有附加在那里。所以每次你获取时,你的列表都会回到原来的状态。

如果其他人来到这里并想使用他们自己已经设置好的 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)
   });

},

然后您可以接收 post 并像这样更新您的 json 文件(在与 comments.json 相同目录中名为 update_json_manager.php 的文件中:

<?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);
?>