开发者问题收集

从父组件向子组件传递数据时出现“TypeError:无法读取未定义的 x 的属性”,但其他组件正常运行

2021-03-02
662

大家好,我有一个项目,它从 API 获得响应,然后将数据从父级传递到子级。问题是,我可以轻松访问顶层的响应,但当我尝试进入 API 的内部部分(在本例中为 price={statistics.quotes.USD.price )时,我收到了 TypeError: Cannot read property 'USD' of undefined 错误。我尝试使用 console.logging 价格来检查我的路径是否正确,结果是正确的。为什么当我可以正确访问其他数据时会发生这种情况?

Overview.js

import React, { useState, useEffect } from 'react';
import Statistics from './Statistics';
import axios from 'axios';

export default function Overview(props) {
    const id = props.match.params.currency;

    //some other states here

    const [statistics, setStatistics] = useState({});

    //some code

    const fetchBasicData = async () => {
        // Retrieves a coin's basic information
        const apiCall = await axios.get('https://api.coinpaprika.com/v1/coins/' + id);
        let basicData = await apiCall.data;

        setCoin(basicData);
            
        // Retrieves coin statistics
        const fetchedData = await axios.get('https://api.coinpaprika.com/v1/tickers/' + id);
        const coinStats = await fetchedData.data;

        setStatistics(coinStats);
    }

    useEffect(function () {
        if (Object.keys(coin).length === 0 && Object.keys(statistics).length === 0) {
            fetchBasicData();
        }
    })

    //some code

    return (
        <div>
            //some other stuff
            <Statistics
                statistics={statistics}
                lastUpdate={statistics.last_updated}
                price={statistics.quotes.USD.price}          // <----- this is where the error occurs
             />
        </div>
    );
}

Statistics.js

import React from 'react';

export default function Statistics(props) {
    return (
        <div>
            <h1>Statistics</h1>
            <p>Last updated: {props.lastUpdate}</p>
            <p>Price: {props.price}</p>
            <p>Market Rank: {props.marketRank}</p>
            <h2>Supply</h2>
            <p>Circulating supply: {props.circulatingSupply}</p>
            <p>Max supply: {props.maxSupply}</p>
        </div>
    );
}
3个回答

您好,可能是您数据中的某些行没有引号,请尝试进行以下更改,应该可以通过此方法修复

price={statistics.quotes.USD.price}

更改为

price={statistics?.quotes?.USD?.price}

?检查给定变量是否存在,如果不存在则返回 null 并且不引发错误

Shashank Padwal
2021-03-02

由于您使用的是 axios 调用,它是异步的,并且该调用的数据在初始渲染时不可用,但稍后将可用。因此,要处理这个问题,您必须进行条件渲染(仅在满足某些条件时渲染)

尝试这个:

price={statistics?.quotes?.USD?.price}

或者您也可以将 Object.hasOwnProperty('key')ternary 一起使用并进行条件渲染。

Mayank Pandeyz
2021-03-02

问题

错误: TypeError:无法读取未定义的属性“USD” 表示 statistics.quotes 未定义。

可能有两个原因:

  1. 在初始渲染时,您对初始状态的访问过深。
  2. 在任何后续渲染中, statistics 都不会更新为您期望的内容。

我猜您的数据获取和状态更新没有问题,这只是初始渲染问题。

初始 statistics 状态是一个空对象 ( {}),因此访问任何属性都没有问题。当您进入更深的嵌套结构级别时,就会导致问题。

<Statistics
  statistics={statistics} // OK: statistics => {}
  lastUpdate={statistics.last_updated} // OK: statistics.last_updated => undefined
  price={statistics.quotes.USD.price} // Error: can't access USD of undefined statistics.quotes
/>
const statistics = {};

console.log(statistics);            // {}
console.log(statistics.quotes);     // undefined
console.log(statistics.qoutes.USD); // error!!

解决方案

您可以使用 可选链接运算符 ( ?. ) 或保护子句(空检查)来防止“访问未定义的 X”错误。

<Statistics
  statistics={statistics}
  lastUpdate={statistics.last_updated}
  price={statistics.quotes?.USD?.price}
/>
<Statistics
  statistics={statistics}
  lastUpdate={statistics.last_updated}
  price={statistics.quotes && statistics.quotes.USD && statistics.quotes.USD.price}
/>

如果您的 statistics 状态有可能更新为 undefined ,则应用与上述相同的修复程序,但级别要浅一些,即 statistics?.quotes?.USD?.price .

或者,您可以应用 Statistics 组件的一些 条件渲染 ,其中条件是 statistics 状态中存在的嵌套属性。

return (
  <div>
    //some other stuff
    {statistics.last_updated && statistics.quotes && (
      <Statistics
        statistics={statistics}
        lastUpdate={statistics.last_updated}
        price={statistics.quotes.USD?.price}
      />
    )}
  </div>
);
Drew Reese
2021-07-17