等待对象数组加载并映射()它。应对

时间:2017-08-20 20:33:03

标签: javascript reactjs

我尝试在使用async XMLHttpRequest()加载后循环遍历json_obj,但由于json_obj在起始map()崩溃时为null。

这是我的代码:

import React, { Component, PropTypes} from 'react';
import ReactDOM from 'react-dom';


class ImageViewer extends React.Component {
    constructor() {
        super();
        this.state = {
            loading: true,
            json_obj : null,
            link: "https://api.github.com/users/github/repos"
        }
    }
    componentDidMount() {
        var xhr = new XMLHttpRequest();
        xhr.open("GET", this.state.link, true);
        xhr.onload = function (e) {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    this.setState({ json_obj :JSON.parse(xhr.responseText).sort(function(a, b){var keyA = new Date(a.updated_at),keyB = new Date(b.updated_at);if(keyA > keyB) return -1;if(keyA < keyB) return 1;return 0;})});
                } else {
                console.error(xhr.statusText);
                }
            }
        }.bind(this);
        xhr.onerror = function (e) {
        console.error(xhr.statusText);
        };
        xhr.send(null);
    }
    render() {
    return (
            <div>
                {this.state.json_obj.map((obj, index) => {
                            return (
                                <div >
                                    <h1>{obj.name}</h1>
                                    <h1>{obj.updated_at}</h1>
                                </div>
                            )
                })}
            </div>
    )
}}
ReactDOM.render(
  <ImageViewer />,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
: <div id="root"></div>

我尝试使用条件渲染,但它也会抛出错误:

import React, { Component, PropTypes} from 'react';
import ReactDOM from 'react-dom';


class ImageViewer extends React.Component {
    constructor() {
        super();
        this.state = {
            loading: true,
            json_obj : null,
            link: "https://api.github.com/users/github/repos",
            stuff : {name:"loading", updated_at:"loading"}
        }
    }
    componentDidMount() {
        var xhr = new XMLHttpRequest();
        xhr.open("GET", this.state.link, true);
        xhr.onload = function (e) {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    this.setState({ json_obj :JSON.parse(xhr.responseText).sort(function(a, b){var keyA = new Date(a.updated_at),keyB = new Date(b.updated_at);if(keyA > keyB) return -1;if(keyA < keyB) return 1;return 0;})});
                } else {
                console.error(xhr.statusText);
                }
            }
        }.bind(this);
        xhr.onerror = function (e) {
        console.error(xhr.statusText);
        };
        xhr.send(null);
    }
    render() {
    return (
            <div>
                {(this.state.json_obj ? this.state.json_obj : this.state.stuff).map((obj, index) => {
                            return (
                                <div >
                                    <h1>{obj.name}</h1>
                                    <h1>{obj.updated_at}</h1>
                                </div>
                            )
                })}
            </div>
    )
}}
ReactDOM.render(
  <ImageViewer />,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

2 个答案:

答案 0 :(得分:2)

因此,检查它是否为null并返回其他内容:

if (!this.state.json_obj) {
  return <div>Loading...</div>;
}

return (
  <div>
    {this.state.json_obj.map((obj, index) => (
      <div key={obj.name}>
        <h1>{obj.name}</h1>
        <h1>{obj.updated_at}</h1>
      </div>
    ))}
  </div>
)

您的代码正在抛出,因为this.state.stuff是一个对象而您无法使用.map迭代对象。如果this.state.json_obj也是对象而不是数组,则需要执行Object.keys(this.state.json_obj).map(...

答案 1 :(得分:1)

您提供的第一个代码会引发错误,因为您提到json_objnull。但是第二个引发错误是因为你试图map超过你不能做的对象this.state.stuff。所以实际上你可以做几件事:

stuff包裹在数组中:

return (
            <div>
                {(this.state.json_obj ? this.state.json_obj : [this.state.stuff]).map((obj, index) => {
                            return (
                                <div >
                                    <h1>{obj.name}</h1>
                                    <h1>{obj.updated_at}</h1>
                                </div>
                            )
                })}
            </div>

或者你可以在定义它时包装它:

constructor() {
    super();
    this.state = {
        loading: true,
        json_obj : null,
        link: "https://api.github.com/users/github/repos",
        stuff : [{name:"loading", updated_at:"loading"}]
    }
}

或者您只需检查json_obj是否可用并改为呈现其他内容(或者没有内容)。

如果json_obj不可用,则无法呈现

return (
            <div>
                {this.state.json_obj && this.state.json_obj.map((obj, index) => {
                            return (
                                <div >
                                    <h1>{obj.name}</h1>
                                    <h1>{obj.updated_at}</h1>
                                </div>
                            )
                })}
            </div>
    )

在json_obj不可用时呈现加载消息

return (
  <div>
    {
    this.state.json_obj ?
      this.state.json_obj.map((obj, index) => {
       return (
         <div >
           <h1>{obj.name}</h1>
           <h1>{obj.updated_at}</h1>
         </div>
       )
     }) : <div>Loading...</div>
    }
   </div>
  )