如何索引到解析的json数组

时间:2015-12-27 19:39:04

标签: jquery json ajax reactjs

我去了reactjs教程here,在完成教程后我开始修补一下。我遇到的一个问题是我无法弄清楚如何索引到某个数组(至少它似乎是一个数组)。以下是从服务器获取数组时的代码:

componentDidMount: 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)
    });
  },

componentDidMount是名为CommentBox的类的Reactjs类定义的一部分,正在解析的json文件看起来像

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

所以现在我尝试更改相同的CommentBox类的render方法来添加一行来打印数据数组的第一个元素。渲染方法变为

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

我添加的行是{this.state.data[0].toString()}。此行会导致错误,指出this.state.data[0]未定义。我怎么能理解this.state.data的元素?它不应该只是一个普通的数组,就好像它是由以下代码设置的吗?

this.state.data = [
    {id: 1, author: "Pete Hunt", text: "This is one comment"},
    {id: 2, author: "Jordan Walke", text: "This is *another* comment"}
];

1 个答案:

答案 0 :(得分:1)

请记住,“Ajax”中的“A”代表异步;在您的数据从服务器返回之前,render被称为 。这意味着第一次调用render时,this.state.data可能未定义(取决于您的getInitialState函数)。

一种常见的方法是添加一个sentinel值,以防止组件完全呈现 - 或呈现不同的内容 - 直到数据可用:

  getInitialState: function() {
    return {
      loaded: false // `loaded` will be our sentinel value
    };
  },

  componentDidMount: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({
          data: data,
          loaded: true // make sure to set `loaded` to true
        });
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },

  render: function() {
        // if the sentinel isn't set, we're not ready
        if (!this.state.loaded) return <div>Loading...</div>;

        return (
          < div className = "commentBox" >
            {this.state.data[0].toString()}
            < h1 > Comments < /h1>
            < CommentList data = {this.state.data} / >
            < CommentForm onCommentSubmit = {this.handleCommentSubmit} / >
          < /div>
        );
  }

或者,您可以检查this.state.data(或其他适当的值)的值,以确定数据是否已准备好呈现。