2015-01-10 3 views
2

Я только что понял, что этот объект в состоянии React, который имеет несколько детей, не может быть легко отображен.react.js - Глубокий объект в состоянии с данными async не работает

В моем примере я компонент, который говорит с третьей стороной API через AJAX:

var Component = React.createClass({ 
    getInitialState: function() { 
    return {data: {}}; 
    }, 

    loadTrackData: function() { 
    api.getDataById(1566285, function (data) { 
     this.setState({data: data}); 
    }.bind(this)); 
    }, 

    componentDidMount: function() { 
    this.loadTrackData(); 
    }, 

    render: function() { 
    return (
     <div> 
      <h2>{this.state.data.metadata.title}</h2> 
     </div> 
    ); 
    } 
}); 

Проблема заключается в том, что {this.state.data.metadata} делает хорошо ..

Но {this.state.data.metadata.title} бросает ошибку Uncaught TypeError: Cannot read property 'title' of undefined!

Каков правильный способ обработки таких данных aync?

+0

Попробуйте использовать метод 'isMounted', как это http://jsbin.com/wunaze/1/edit?js –

+0

@Alexander это не помогает – Kosmetika

+0

вы изменили' getInitialState', как в примере? –

ответ

2

this.state.data.metadataundefined до загрузки происходит. Доступ к любому объекту на undefined дает вам TypeError. Это не является специфическим для React - именно так работают ссылки на объекты JavaScript.

Предлагаю вам использовать { data: null } в исходном состоянии и вернуть что-то еще от render с условием if (!this.state.data).

4

Мне всегда нравится добавлять указатель загрузки или индикатор, если на странице работает асинхронный режим. Я бы сделал это

var Component = React.createClass({ 
    getInitialState: function() { 
    return {data: null}; 
    }, 

    loadTrackData: function() { 
    api.getDataById(1566285, function (data) { 
     this.setState({data: data}); 
    }.bind(this)); 
    }, 

    componentDidMount: function() { 
    this.loadTrackData(); 
    }, 

    render: function() { 
    var content = this.state.data ? <h2>{this.state.data.metadata.title}</h2> : <LoadingIndicator />; 
    return (
     <div> 
     {content} 
     </div> 
    ); 
    } 
}); 

с индикатором загрузки в основном это улучшает пользовательский интерфейс и не будет получать много неприятного сюрприза. u может создать свой собственный компонент индикатора загрузки с большим количеством вариантов здесь http://loading.io/

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

  • Нет связанных вопросов^_^