2016-09-07 4 views
0

Как новичок, я пытался создать свое первое приложение Реагировать следующий учебник: https://facebook.github.io/react/docs/tutorial.htmlTypeError: this.props.data.map не является функцией

Мой сервер был запущен в http://localhost:3000 после выполнения команды: PERL сервер .pl

Эта ошибка была сгенерирована (если смотреть на FireBug): TypeError: this.props.data.map не является функцией

Вот мой код

файла: index.html

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <title>React Tutorial</title> 
    <!-- Not present in the tutorial. Just for basic styling. --> 
    <link rel="stylesheet" href="css/base.css" /> 
    <script src="https://unpkg.com/[email protected]/dist/react.js"></script> 
    <script src="https://unpkg.com/[email protected]/dist/react-dom.js"></script> 
    <script src="https://unpkg.com/[email protected]/babel.min.js"></script> 
    <script src="https://unpkg.com/[email protected]/dist/jquery.min.js"></script> 
    <script src="https://unpkg.com/[email protected]/dist/remarkable.min.js"></script> 
    </head> 
    <body> 
    <div id="content"></div> 

    <script type="text/babel"> 

    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> 
      {this.props.children} 
      </div> 
     ); 
     } 
    }); 

    var CommentBox = React.createClass 
    ({ 
     loadCommentsFromServer: function() 
     {    
      $.ajax({ 
       url: this.props.url, 
       dataType: 'json', 
       cache: false, 
       success: function(data) { 
       this.setState({data: data}); 
       }.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; 
      // Optimistically set an id on the new comment. It will be replaced by an 
      // id generated by the server. In a production application you would likely 
      // not use Date.now() for this and would have a more robust system in place. 
      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) { 
      //alert(e.target.value); 
      this.setState({author: e.target.value}); 
      }, 
      handleTextChange: function(e) { 
      //alert(e.target.value); 
      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; 
      } 
      // TODO: send request to the server 
      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="/api/comments" pollInterval={2000} />, 
     document.getElementById('content') 
    ); 

    </script> 
    </body> 
</html> 

Файл: comments.json

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

Исключить исключения и изучить значение 'this.props.data'. –

ответ

2

<CommentList data="{this.state.data}" />

this.state.data НЕ должно быть в двойных кавычках.

Ошибка возникает, когда this.props.data не определен или не является массивом. Прежде чем делать карту, попробуйте указать значение по умолчанию следующим образом.

const data = this.props.data || []; 
data.map(...); 
+0

<КомментарийList data = {this.state.data} /> , который работает !!! –

Смежные вопросы