2014-07-11 4 views
21

Я следую учебному курсу reactjs, и я продолжаю сталкиваться с проблемой при передаче значения из состояния одного компонента в другой компонент. Ошибка «Невозможно прочитать свойство« map undefined »вызывается при выполнении функции map в компоненте CommentList. Что может заставить опору стать неопределенным при переходе из CommentBox в CommentList?Невозможно прочитать свойство 'map' of undefined

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

    var CommentBox = React.createClass({ 
    getInitialState: function(){ 
     return {data: []}; 
    }, 
    getComments: function(){ 
     $.ajax({ 
     url: this.props.url, 
     dataType: 'json', 
     success: function(data){ 
      this.setState({data: data}); 
     }.bind(this), 
     error: function(xhr, status, err){ 
      console.error(url, status, err.toString()); 
     }.bind(this) 
     }); 
    }, 
    componentWillMount: function(){ 
     this.getComments() 
    }, 
    render: function(){ 
     return (
     <div className="commentBox"> 
      {/*this.state.data.comments*/} 
      {<CommentList data={this.state.data.comments}/>} 
     </div> 
    ); 
    } 
    }); 

    React.renderComponent(
    <CommentBox url="comments.json" />, 
    document.getElementById('content') 
); 

ответ

16

Прежде всего, установить более безопасный исходные данные:

getInitialState : function() { 
    return {data: {comments:[]}}; 
}, 

и обеспечить ваши данные АЯКС.

Он должен работать, если вы будете следовать выше двух команд, как Demo.

Обновлено: вы можете просто обернуть блок .map с условным оператором.

if (this.props.data) { 
    var commentNodes = this.props.data.map(function (comment){ 
     return (
     <div> 
      <h1>{comment.author}</h1> 
     </div> 
    ); 
    }); 
} 
+1

Это решение сработало, но мне любопытно. Если у меня будет более сложная структура JSON, мне придется инициализировать объект данных таким же образом? Кажется, должен быть лучший способ. Спасибо – Nael

+0

@Nael Нет, вам не нужно. Просто заверните блок, как показано выше. :) – taggon

+0

Это работает, но в чем причина ошибки? – Cheng

5

Я думаю, что вы забыли изменить

data={this.props.data} 

в

data={this.state.data} 

в функции визуализации CommentBox. Я сделал ту же ошибку, когда я следил за учебником. Таким образом, все визуализации функция должна выглядеть

render: function() { 
    return (
    <div className="commentBox"> 
     <h1>Comments</h1> 
     <CommentList data={this.state.data} /> 
     <CommentForm /> 
    </div> 
); 
} 

вместо

render: function() { 
    return (
    <div className="commentBox"> 
     <h1>Comments</h1> 
     <CommentList data={this.props.data} /> 
     <CommentForm /> 
    </div> 
); 
4

Вы должны поместить данные перед визуализацией

Должно быть так:

var data = [ 
    {author: "Pete Hunt", text: "This is one comment"}, 
    {author: "Jordan Walke", text: "This is *another* comment"} 
]; 

React.render(
    <CommentBox data={data}/>, 
    document.getElementById('content') 
); 

Вместо это:

React.render(
    <CommentBox data={data}/>, 
    document.getElementById('content') 
); 

var data = [ 
    {author: "Pete Hunt", text: "This is one comment"}, 
    {author: "Jordan Walke", text: "This is *another* comment"} 
]; 
Смежные вопросы