我正在使用coinmarketcap api构建一个简单的加密货币应用程序。我的get请求在componentDidMount内部。当我console.log在异步函数内部和在渲染内部接收到的对象时-它起作用。但是当我实际尝试在return(h3元素)中显示接收到的数据时,接收到的对象变得不确定。我收到一个typeError“无法读取未定义的属性url”。我在这里做什么错了?
import React, { Component } from "react";
import axios from "axios";
import { Row, Col, Badge } from "react-bootstrap";
class Crypto extends Component {
constructor(props) {
super(props);
this.state = {
singleCrypto: {},
id: this.props.match.params.id
};
}
componentDidMount() {
this.getEachCrypto();
}
async getEachCrypto() {
try {
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const id = this.props.match.params.id;
let data = await axios.get(
proxyurl +
"https://pro-api.coinmarketcap.com/v1/cryptocurrency/info?id=" +
id,
{
headers: {
"X-CMC_PRO_API_KEY": "e1eb1f30-5c4e-43aa-be04-4b50df00807a"
}
}
);
this.setState({ singleCrypto: data.data.data });
} catch (error) {
console.log("request failed", error);
}
console.log(
this.state.singleCrypto[this.props.match.params.id].urls.website[0]
); // this works
}
render() {
const { singleCrypto } = this.state;
if (Object.keys(singleCrypto).length === 0) {
console.log("Loading");
} else {
console.log(singleCrypto[this.props.match.params.id].urls.website[0]); // this works
}
return (
<div>
<div className="crypto fluid">
<Row>
<Col lg md={3}>
<h3>
{singleCrypto[this.props.match.params.id].urls.website[0]} // fails!!!
</h3>
<div>
<ul>
<li>Rank</li>
<li>Website</li>
<li>Explorer</li>
<li>Message Board</li>
<li>Source Code</li>
<li>Tech Docs</li>
<li>Tags</li>
</ul>
</div>
</Col>
<Col lg md={7}>
<h3>Price, % change</h3>
<Badge variant="primary">Buy</Badge>
<Badge variant="primary">Exchange</Badge>
<Badge variant="primary">Gamble</Badge>
<Badge variant="primary">Earn Crypto</Badge>
</Col>
<Col lg md={2}>
2 parts
</Col>
</Row>
</div>
</div>
);
}
}
export default Crypto;
这是我的数据示例:
"data": {
"1": {
"urls": {
"website": [
"https://bitcoin.org/"
],
"technical_doc": [
"https://bitcoin.org/bitcoin.pdf"
],
"twitter": [],
"reddit": [
"https://reddit.com/r/bitcoin"
],
"message_board": [
"https://bitcointalk.org"
],
答案 0 :(得分:1)
当数据不可用时,您必须return null
或loading state
if (Object.keys(singleCrypto).length === 0) {
return null; // you can maintain a loading state too untill data is available
}
处于加载状态
class Crypto extends Component {
constructor(props) {
super(props);
this.state = {
singleCrypto: {},
id: this.props.match.params.id.
isLoading: true,
};
}
componentDidMount() {
this.getEachCrypto();
}
async getEachCrypto() {
try {
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const id = this.props.match.params.id;
this.setState({isLoading: true});
let data = await axios.get(
proxyurl +
"https://pro-api.coinmarketcap.com/v1/cryptocurrency/info?id=" +
id,
{
headers: {
"X-CMC_PRO_API_KEY": "e1eb1f30-5c4e-43aa-be04-4b50df00807a"
}
}
);
this.setState({ singleCrypto: data.data.data, isLoading: false });
} catch (error) {
console.log("request failed", error);
this.setState({ isLoading: false });
}
}
render() {
const { singleCrypto } = this.state;
if(this.state.isLoading) {
return <div>Loading...<div>
}
...
}
}
export default Crypto;