【问题标题】:'TypeError: Cannot read property of x of undefined' when passing data from parent to child component but others are working'TypeError: Cannot read property of x of undefined' 将数据从父组件传递到子组件但其他组件正在工作时
【发布时间】:2021-06-01 00:22:34
【问题描述】:

美好的一天,我有一个项目从 API 获取响应,然后将数据从父级传递给子级。问题是,我可以轻松访问顶层的响应,但是当我尝试进入 API 的内部部分(在本例中为 price={statistics.quotes.USD.price})时,我收到了 TypeError: Cannot read property 'USD' of undefined 错误。我已经尝试过控制台。记录价格以检查我的路径是否正确。当我可以正确访问其他数据时,为什么会发生这种情况?

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>
    );
}

【问题讨论】:

  • 查看实际的 JSON 响应会很有用。命名约定“引号”让我觉得它应该是一个数组——即使它只有一个对象,所以你需要访问正确的索引。但错误暗示quotes 未定义
  • 这是来自 API 的示例响应(ID 为“eth-ethereum”)。 ibb.co/XCCrRRH我可以轻松访问名称、符号等。但是当我尝试访问价格时却卡住了。

标签: javascript json reactjs frontend typeerror


【解决方案1】:

问题

错误:TypeError: Cannot read property 'USD' of undefined 表示 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!!

解决方案

您可以使用Optional Chaining operator (?.) 或保护子句(空检查)来保护“未定义的访问 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 组件的一些Conditional Rendering,条件是statistics 状态上存在的嵌套属性。

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

【讨论】:

    【解决方案2】:

    当您使用 axios 调用时,它是异步的,并且该调用的数据在初始渲染时不可用,但稍后将可用。所以要处理这个你必须条件渲染(仅在满足特定条件时渲染)

    试试这个:

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

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

    【讨论】:

      【解决方案3】:

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

      改变

      price={statistics.quotes.USD.price}
      

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

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

      【讨论】:

        猜你喜欢
        • 2021-05-24
        • 2021-06-25
        • 2020-11-12
        • 2020-02-07
        • 2017-04-24
        • 2023-03-15
        • 2022-01-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多