-1

我一直在做一个 React 项目,同时从 rapidAPI 获取数据。但是每当我朗姆酒我的项目时,我都会一次又一次地遇到这个错误。

TypeError: Cannot read properties of undefined (reading 'total')
Homepage
src/components/Homepage.jsx:23
  20 | <>
  21 |   <Title level={2} className="heading">Global Crypto Stats</Title>
  22 |   <Row gutter={[32, 32]}>
> 23 |     <Col span={12}><Statistic title="Total Cryptocurrencies" value={globalStats.total} /></Col>
     | ^  24 |     <Col span={12}><Statistic title="Total Exchanges" value={millify(globalStats.totalExchanges)} /></Col>
  25 |     <Col span={12}><Statistic title="Total Market Cap:" value={`$${millify(globalStats.totalMarketCap)}`} /></Col>
  26 |     <Col span={12}><Statistic title="Total 24h Volume" value={`$${millify(globalStats.total24hVolume)}`} /></Col>

这是我一直在寻找调试的文件。

应用程序.js

import React from 'react';
import { Switch, Route, Link } from 'react-router-dom';
import { Layout, Typography, Space } from 'antd';

import { Exchanges, Homepage, News, Cryptocurrencies, CryptoDetails, Navbar } from './components';
import './App.css';

const App = () => (
  <div className="app">
    <div className="navbar">
      <Navbar />
    </div>
    <div className="main">
      <Layout>
        <div className="routes">
          <Switch>
            <Route exact path="/">
              <Homepage />
            </Route>
            <Route exact path="/exchanges">
              <Exchanges />
            </Route>
            <Route exact path="/cryptocurrencies">
              <Cryptocurrencies />
            </Route>
            <Route exact path="/crypto/:coinId">
              <CryptoDetails />
            </Route>
            <Route exact path="/news">
              <News />
            </Route>
          </Switch>
        </div>
      </Layout>
      <div className="footer">
        <Typography.Title level={5} style={{ color: 'white', textAlign: 'center' }}>Copyright © 2021
          <Link to="/">
            Cryptoverse Inc.
          </Link> <br />
          All Rights Reserved.
        </Typography.Title>
        <Space>
          <Link to="/">Home</Link>
          <Link to="/exchanges">Exchanges</Link>
          <Link to="/news">News</Link>
        </Space>
      </div>
    </div>
  </div>
);

export default App;

主页.jsx

import React from 'react';
import millify from 'millify';
import { Typography, Row, Col, Statistic } from 'antd';
import { Link } from 'react-router-dom';

import { useGetCryptosQuery } from '../services/cryptoApi';
import Cryptocurrencies from './Cryptocurrencies';
import News from './News';
import Loader from './Loader';

const { Title } = Typography;

const Homepage = () => {
  const { data, isFetching } = useGetCryptosQuery(10);
  const globalStats = data?.data?.stats;

  if (isFetching) return <Loader />;

  return (
    <>
      <Title level={2} className="heading">Global Crypto Stats</Title>
      <Row gutter={[32, 32]}>
        <Col span={12}><Statistic title="Total Cryptocurrencies" value={globalStats.total} /></Col>
        <Col span={12}><Statistic title="Total Exchanges" value={millify(globalStats.totalExchanges)} /></Col>
        <Col span={12}><Statistic title="Total Market Cap:" value={`$${millify(globalStats.totalMarketCap)}`} /></Col>
        <Col span={12}><Statistic title="Total 24h Volume" value={`$${millify(globalStats.total24hVolume)}`} /></Col>
        <Col span={12}><Statistic title="Total Cryptocurrencies" value={globalStats.total} /></Col>
        <Col span={12}><Statistic title="Total Markets" value={millify(globalStats.totalMarkets)} /></Col>
      </Row>
      <div className="home-heading-container">
        <Title level={2} className="home-title">Top 10 Cryptos In The World</Title>
        <Title level={3} className="show-more"><Link to="/cryptocurrencies">Show more</Link></Title>
      </div>
      <Cryptocurrencies simplified />
      <div className="home-heading-container">
        <Title level={2} className="home-title">Latest Crypto News</Title>
        <Title level={3}><Link to="/news">Show more</Link></Title>
      </div>
      <News simplified />
    </>
  );
};

export default Homepage;

服务/cryptoApi.js

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

const cryptoApiHeaders = {
    'x-rapidapi-host': 'coinranking1.p.rapidapi.com',
    'x-rapidapi-key': '268c978691mshf443e1a9132dfdep1f3fe3jsn953b6183c440',
};

const baseUrl = 'https://coinranking1.p.rapidapi.com';

const createRequest = (url) => ({ url, headers: cryptoApiHeaders });

export const cryptoApi = createApi({
    reducerPath: 'cryptoApi',
    baseQuery: fetchBaseQuery({ baseUrl }),
    endpoints: (builder) => ({
      getCryptos: builder.query({
        query: (count) => createRequest(`/coins/?limit=${count}`),
      }),
      getExchanges: builder.query({
        query: () => createRequest('/exchanges'),
      }),
      getCryptoDetails: builder.query({
        query: (coinId) => createRequest(`/coin/${coinId}`),
      }),
      getCryptoHistory: builder.query({
        query: ({ coinId, timeperiod }) => createRequest(`coin/${coinId}/history/${timeperiod}`),
      }),
    }),
  });

export const {
    useGetCryptosQuery,
    useGetCryptoDetailsQuery,
    useGetCryptoHistoryQuery,
    useGetExchangesQuery,
} = cryptoApi;

我已经尝试了很多,但情况仍在继续。任何帮助将不胜感激。先感谢您。

4

4 回答 4

2

当你传递value给你的<Col />标签时src/components/Homepage.jsx:23,你通过了globalStats.total

但是当应用程序到达这一行时,globalStats仍然是空的。你应该处理在这种情况下该怎么做

例如,您可以null condition像这样检查何时阅读它:

value={globalStats?.total} 

或者,当您像这样声明主变量时,您可能想声明一个默认值:

  const globalStats = data?.data?.stats ?? {}
  // globalStats will be an empty object if your data?.data?.stats be empty 

或者如果它是空的,也许你想显示加载:

  const globalStats = data?.data?.stats;
  if (isFetching || !globalStats) return <Loader />;
于 2022-02-12T06:31:27.863 回答
1

不确定这是否会有所帮助,但您是否尝试过仅在有 globalStats 时才进行渲染?例子 :

 return (
    <>
{globalstats?  <>
      <Title level={2} className="heading">Global Crypto Stats</Title>
      <Row gutter={[32, 32]}>
        <Col span={12}><Statistic title="Total Cryptocurrencies" value={globalStats.total} /></Col>
        <Col span={12}><Statistic title="Total Exchanges" value={millify(globalStats.totalExchanges)} /></Col>
        <Col span={12}><Statistic title="Total Market Cap:" value={`$${millify(globalStats.totalMarketCap)}`} /></Col>
        <Col span={12}><Statistic title="Total 24h Volume" value={`$${millify(globalStats.total24hVolume)}`} /></Col>
        <Col span={12}><Statistic title="Total Cryptocurrencies" value={globalStats.total} /></Col>
        <Col span={12}><Statistic title="Total Markets" value={millify(globalStats.totalMarkets)} /></Col>
      </Row>
      <div className="home-heading-container">
        <Title level={2} className="home-title">Top 10 Cryptos In The World</Title>
        <Title level={3} className="show-more"><Link to="/cryptocurrencies">Show more</Link></Title>
      </div>
      <Cryptocurrencies simplified />
      <div className="home-heading-container">
        <Title level={2} className="home-title">Latest Crypto News</Title>
        <Title level={3}><Link to="/news">Show more</Link></Title>
      </div>
      <News simplified />
</> : <> "" </> }
    </>
  );
于 2022-02-12T06:28:46.140 回答
1

globalStats此处未定义;在此错误发生时。您可以使用可选的链接运算符?.( value={globalStats?.total}):

<Col span={12}><Statistic title="Total Cryptocurrencies" value={globalStats?.total} /></Col>

或者您可以在未定义null时返回:globalStats

if (!globalStats) return null;
于 2022-02-12T06:29:59.440 回答
1

看起来像在Homepage.jsx你打电话时globalStats- 它是undefined.

您可以使用问号检查对象是否存在:

<Col span={12}><Statistic title="Total Cryptocurrencies" value={globalStats?.total} />

或者您可以在片段之外添加一个检查,以仅在 globalStats存在时显示内容:

return globalStats ? (<><Title>Global Crypto Stats</Title><>the rest...</></>) : null;
于 2022-02-12T06:33:12.413 回答