未捕获的TypeError:this.props.data.map不是函数

时间:2016-06-30 06:34:28

标签: javascript jquery json django reactjs

我不确定为什么我收到此错误,我修改了教程中的代码,以便this.setState({data: data});变为this.setState({data: data.datalist});以反映后端的响应。我已根据此答案对代码进行了更改,但同样的错误仍然存​​在React JS - Uncaught TypeError: this.props.data.map is not a function

教程中的示例代码配置为从我的后端获取JSON:

import React from 'react'
import ReactDOM from 'react-dom'
import $ from 'jquery'

var Comment = React.createClass({
  rawMarkup: function() {
    var md = new Remarkable();
    var rawMarkup = md.render(this.props.children.toString());
    return { __html: rawMarkup };
  },

  render: function() {
    return (
      <div className="comment">
        <h2 className="commentAuthor">
          {this.props.author}
        </h2>
        <span dangerouslySetInnerHTML={this.rawMarkup()} />
      </div>
    );
  }
});

var CommentBox = React.createClass({
  loadCommentsFromServer: function() {
    $.ajax({cache:false});
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      success: function(data) {
        console.log(data.datalist);
        this.setState({data: data.datalist});
      }.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;
    comment.id = Date.now();
    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) {
        this.setState({data: comments});
        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>
    );
  }
});

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

var CommentForm = React.createClass({
  getInitialState: function() {
    return {author: '', text: ''};
  },
  handleAuthorChange: function(e) {
    this.setState({author: e.target.value});
  },
  handleTextChange: function(e) {
    this.setState({text: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    var author = this.state.author.trim();
    var text = this.state.text.trim();
    if (!text || !author) {
      return;
    }
    this.props.onCommentSubmit({author: author, text: text});
    this.setState({author: '', text: ''});
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input
          type="text"
          placeholder="Your name"
          value={this.state.author}
          onChange={this.handleAuthorChange}
        />
        <input
          type="text"
          placeholder="Say something..."
          value={this.state.text}
          onChange={this.handleTextChange}
        />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

ReactDOM.render(
  <CommentBox url="/core/get_json" pollInterval={2000} />,
  document.getElementById('app')
);

来自后端的JSON(django):

def get_json(request):

    return JsonResponse({'datalist': [
        {'id': 1, 'author': "Pete Hunt", 'text': "This is one comment"},
        {'id': 2, 'author': "Jordan Walke", 'text': "This is *another* comment"}
    ]})

浏览器在网络响应下获得JSON:

{"datalist": [{"id": 1, "author": "Pete Hunt", "text": "This is one comment"}, {"id": 2, "author": "Jordan Walke", "text": "This is *another* comment"}]}

2 个答案:

答案 0 :(得分:0)

渲染立即调用this.props.data,您的数据可能尚未到达,因此您需要检查数据是否准备好,方法是 this.props.data && this.props.data.map

var commentNodes = this.props.data && this.props.data.map(function(comment) 
{
  return (
    <Comment author={comment.author} key={comment.id}>
      {comment.text}
    </Comment>
  );
});

答案 1 :(得分:0)

map函数被调用两次,一次在请求之前,一次在请求之后。要更正此问题,您可以使用

      {this.props.data.length > 0 && this.props.data.map()}

这可以解决问题。