在卡片组件中显示道具的问题-React
2020-04-14
213
我正在使用开源 API 在 React 中构建跟踪器应用程序。我正在使用 Axios 进行 HTTP 请求。当我传递从 index.js 中的 GET 函数检索到的对象时,我收到一条错误消息:
TypeError:无法读取未定义的属性“NewConfirmed”
根据以下代码,有人知道为什么会发生这种情况以及为什么参数返回未定义?我试图更改参数的解构以反映 API 构造它的方式,但没有成功。
index.js
import axios from 'axios';
const url = 'https://api.covid19api.com/summary';
export const fetchData = async () => {
try {
const { data: { Global: { NewConfirmed, TotalConfirmed, NewDeaths, TotalDeaths, NewRecovered, TotalRecovered, } } } = await axios.get(url);
return { NewConfirmed, TotalConfirmed, NewDeaths, TotalDeaths, NewRecovered, TotalRecovered, } ;
} catch (error) {
console.log(error);
}
}
App.js
import React from 'react';
import {Cards, Chart, CountryPicker} from './components';
import styles from './App.module.css';
import {fetchData} from './api';
class App extends React.Component {
state ={
data: {},
}
async componentDidMount() {
const fetchedData = await fetchData();
this.setState({data: fetchedData});
}
render() {
const { data } = this.state;
return(
<div className={styles.container}>
<Cards data = {data} />
<CountryPicker />
<Chart />
</div>
);
}
}
export default App;
Cards.jsx
import React from 'react';
import {Card, CardContent, Typography, Grid} from '@material-ui/core';
import styles from './Cards.module.css';
const Cards = ({data: { Global: { NewConfirmed, TotalConfirmed, NewDeaths, TotalDeaths, NewRecovered, TotalRecovered } } }) => {
return(
<div className = {styles.container}>
<Grid container spacing={3} justify="center">
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>New Confirmed</Typography>
<Typography variant="h5">{NewConfirmed.value}</Typography>
<Typography color="textSecondary">REAL DATE</Typography>
<Typography variant="body2">Number of active cases of COVID-19.</Typography>
</CardContent>
</Grid>
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>Total Confirmed</Typography>
<Typography variant="h5">{TotalConfirmed.value}</Typography>
<Typography color="textSecondary">REAL DATE</Typography>
<Typography variant="body2">Number of active cases of COVID-19.</Typography>
</CardContent>
</Grid>
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>New Deaths</Typography>
<Typography variant="h5">{NewDeaths.value}</Typography>
<Typography color="textSecondary">REAL DATE</Typography>
<Typography variant="body2">Number of active cases of COVID-19.</Typography>
</CardContent>
</Grid>
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>Total Deaths</Typography>
<Typography variant="h5">REAL DATA</Typography>
<Typography color="textSecondary">REAL DATE</Typography>
<Typography variant="body2">Number of recoveries of COVID-19.</Typography>
</CardContent>
</Grid>
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>New Recovered</Typography>
<Typography variant="h5">REAL DATA</Typography>
<Typography color="textSecondary">REAL DATE</Typography>
<Typography variant="body2">Number of deaths of COVID-19.</Typography>
</CardContent>
</Grid>
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>Total Recovered</Typography>
<Typography variant="h5">REAL DATA</Typography>
<Typography color="textSecondary">REAL DATE</Typography>
<Typography variant="body2">Number of deaths of COVID-19.</Typography>
</CardContent>
</Grid>
</Grid>
</div>
)
}
export default Cards;
2个回答
在 fetchData 中,您读取的是 Global 对象,但您返回的只是 Global 对象的内容,而不是 Global 本身。然后在 Cards 中,您再次以 Global 形式接收 props,但这只是 Global 内容。
您有:
const Cards = ({data: { Global: { NewConfirmed, TotalConfirmed, NewDeaths, TotalDeaths...
但应该是:
const Cards = ({data: { NewConfirmed, TotalConfirmed, NewDeaths, TotalDeaths...
HermitCrab
2020-04-14
您在 compountDidMount 之后(即调用 render 方法时)获取 API 结果。因此您的组件在渲染时没有任何数据,并且由于您的 API 调用尚未完成,因此
NewConfirmed
未定义。
尝试在渲染组件之前添加检查。
import React from 'react';
import {Card, CardContent, Typography, Grid} from '@material-ui/core';
import styles from './Cards.module.css';
const Cards = ({data: { Global: { NewConfirmed, TotalConfirmed, NewDeaths, TotalDeaths, NewRecovered, TotalRecovered } } }) => {
if (!NewConfirmed) return null;
return(
<div className = {styles.container}>
<Grid container spacing={3} justify="center">
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>New Confirmed</Typography>
<Typography variant="h5">{NewConfirmed.value}</Typography>
<Typography color="textSecondary">REAL DATE</Typography>
<Typography variant="body2">Number of active cases of COVID-19.</Typography>
</CardContent>
</Grid>
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>Total Confirmed</Typography>
<Typography variant="h5">{TotalConfirmed.value}</Typography>
<Typography color="textSecondary">REAL DATE</Typography>
<Typography variant="body2">Number of active cases of COVID-19.</Typography>
</CardContent>
</Grid>
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>New Deaths</Typography>
<Typography variant="h5">{NewDeaths.value}</Typography>
<Typography color="textSecondary">REAL DATE</Typography>
<Typography variant="body2">Number of active cases of COVID-19.</Typography>
</CardContent>
</Grid>
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>Total Deaths</Typography>
<Typography variant="h5">REAL DATA</Typography>
<Typography color="textSecondary">REAL DATE</Typography>
<Typography variant="body2">Number of recoveries of COVID-19.</Typography>
</CardContent>
</Grid>
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>New Recovered</Typography>
<Typography variant="h5">REAL DATA</Typography>
<Typography color="textSecondary">REAL DATE</Typography>
<Typography variant="body2">Number of deaths of COVID-19.</Typography>
</CardContent>
</Grid>
<Grid item component={Card}>
<CardContent>
<Typography color="textSecondary" gutterBottom>Total Recovered</Typography>
<Typography variant="h5">REAL DATA</Typography>
<Typography color="textSecondary">REAL DATE</Typography>
<Typography variant="body2">Number of deaths of COVID-19.</Typography>
</CardContent>
</Grid>
</Grid>
</div>
)
}
export default Cards;
Mukund Goel
2020-04-14