[英]Wait for object array to load and map() it. React
I am trying to loop through json_obj after it loads using async XMLHttpRequest()
but as json_obj is null at the start map() crashes. 我尝试使用异步
XMLHttpRequest()
加载后遍历json_obj,但由于json_obj在开始map()崩溃时为null。
Here is my code: 这是我的代码:
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>
I tried to use conditional rendering but it throws errors as well: 我尝试使用条件渲染,但它也会引发错误:
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>
So check if it's null and return something else: 因此,检查它是否为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>
)
Your code was throwing because this.state.stuff
is an object and you can't iterate over an object with .map
. 您的代码被抛出,因为
this.state.stuff
是一个对象,您无法使用.map
遍历对象。 If this.state.json_obj
is also an object and not an array you would need to do Object.keys(this.state.json_obj).map(...
. 如果
this.state.json_obj
也是对象而不是数组,则需要执行Object.keys(this.state.json_obj).map(...
The first code you provided throws an error because json_obj
is null
as you mentioned. 您提供的第一个代码会引发错误,因为您提到的
json_obj
为null
。 But the second one throws an error because you are trying to map
over the object this.state.stuff
which you can not do. 但是第二个抛出一个错误,因为您试图
map
无法执行的对象this.state.stuff
。 So there are actually a couple of things you can do: 因此,实际上您可以做几件事:
wrap stuff
inside an array: 将
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>
or you can wrap it when defining it: 或者您可以在定义它时将其包装:
constructor() {
super();
this.state = {
loading: true,
json_obj : null,
link: "https://api.github.com/users/github/repos",
stuff : [{name:"loading", updated_at:"loading"}]
}
}
or you can simply check if json_obj
is available and rendering something else (or nothing) instead. 或者您可以简单地检查
json_obj
是否可用,然后呈现其他内容(或什么都不显示)。
renders nothing if json_obj
is not available 如果
json_obj
不可用, 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>
)
renders a loading message when json_obj is not available 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>
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.