开发者问题收集

在卡片组件中显示道具的问题-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