简体   繁体   中英

react.js - Deep Object in state with async data does not work

I've just figured out that object in React's state that have multiple children cannot be rendered easily.

In my example I have component which speaks with third-party API through 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>
    );
  }
});

The problem is that {this.state.data.metadata} renders fine..

But {this.state.data.metadata.title} throws error Uncaught TypeError: Cannot read property 'title' of undefined !

What is the proper way to deal with such async data?

I always like to add the loading spinner or indicator if the page has async operation. I would do this

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

with the loading indicator basically it improve the user experience and won't get much of unwanted surprise. u can create your own loading indicator component with lots of choices here http://loading.io/

this.state.data.metadata is undefined until loading occurs. Accessing any property on undefined gives you a TypeError . This is not specific to React—it's just how JavaScript object references work.

I suggest you use { data: null } in initial state and return something else from render with a condition like if (!this.state.data) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM