【问题标题】:ReactJS: value of the object is undefinedReactJS:对象的值未定义
【发布时间】:2020-12-05 08:16:54
【问题描述】:

我正在尝试制作一个显示 Covid 19 号码的应用程序。我想在渲染组件时显示全局数字,所以我为此使用了 useEffect 钩子。当我尝试显示global.confirmed 时,它返回一个对象,但是当我尝试显示global.confirmed.value 时,我得到Cannot read property 'value' of undefined 错误。我该如何解决这个问题?

import React from "react";
import "./App.css";
import axios from "axios";
import { useState, useEffect } from "react";
import "./App.css";

const App = () => {
  const [countries, SetCountries] = useState([]);
  const [cases, SetCases] = useState([]);
  const [global, SetGlobal] = useState({});

  const urlGlobal = "https://covid19.mathdro.id/api/"
  const urlCountries = "https://covid19.mathdro.id/api/countries/";

  useEffect(() => {
    axios.get(urlGlobal).then(res => SetGlobal(res.data))
    axios.get(urlCountries).then((res) => SetCountries(res.data.countries));
  }, []);

  const showCases = (e) => {
    const urlCases = `https://covid19.mathdro.id/api/countries/${e.target.value}`;
    axios.get(urlCases).then((res) => SetCases(res.data));
  };


  return (
    <div>
      <div>
        <p>Infected</p>
        <p>{cases.confirmed.value}</p>
        <p>{cases.lastUpdate}</p>
        <p>Number of active cases of COVID-19</p>
      </div>
      <div>
        <p>Recovered</p>
        <p>{cases.recovered.value}</p>
        <p>{cases.lastUpdate}</p>
        <p>Number of recoveries from COVID-19</p>
      </div>
      <div>
        <p>Deaths</p>
        <p>{cases.deaths.value}</p>
        <p>{cases.lastUpdate}</p>
        <p>Number of deaths caused by COVID-19</p>
      </div>
      <select name="countries" onChange={(e) => showCases(e)}>
        {countries.map((val, i) => (
          <option key={i} value={val.name}>
            {val.name}
          </option>
        ))}
      </select>
    </div>
  );
};

export default App;

全球:

【问题讨论】:

  • 当你显示cases.confirmed 时发生了什么?你说你得到一个对象,但你能看看里面是否有任何字段吗?
  • 当你的组件第一次挂载时,数据还没有被获取。所以在第一次渲染时cases 是你传递给useState 的空数组。
  • @Maxime 我添加了截图。

标签: reactjs axios react-hooks


【解决方案1】:

默认情况下,您将cases 设置为一个空数组:

const [cases, SetCases] = useState([]);

在初始渲染时,虽然它仍然是一个空数组,但您尝试访问未在数组上定义的属性:

<p>{cases.confirmed.value}</p>

这里基本上有两个问题:

  1. 数组没有像confirmed 这样的属性。您是否希望 cases 改为对象?
  2. 当组件首次渲染时,cases 没有数据,所以不要尝试显示该数据。

casesundefined 开头(因为在使用中它看起来甚至不应该是一个数组):

const [cases, SetCases] = useState();

并且只在不是undefined时才显示:

<div>
  <p>Infected</p>
  <p>{cases && cases.confirmed.value}</p>
  <p>{cases && cases.lastUpdate}</p>
  <p>Number of active cases of COVID-19</p>
</div>

您可以重复其他用法,或将所有用法包含在单个检查中以检查 cases

{
  cases &&
  <div>
    <p>Infected</p>
    <p>{cases.confirmed.value}</p>
    <p>{cases.lastUpdate}</p>
    <p>Number of active cases of COVID-19</p>
  </div>
}

这个想法是,如果 cases 是“假”(undefined 是),这些元素甚至不会尝试渲染,因此代码不会尝试访问像 confirmed 这样的属性,直到 cases存在。


然而如果cases应该是一个数组,那么你还有一个整体标记结构中的逻辑错误,因为数组没有像confirmed 这样的属性。也许您打算从数组中计算值。如果是这种情况,那么您可以将初始状态保留为空数组:

const [cases, SetCases] = useState([]);

但是您需要将标记更改为使用数组的内容。例如,可能是这样的:

{
  cases.map(c => (
    <div>
      <p>Infected</p>
      <p>{c.confirmed.value}</p>
      <p>{c.lastUpdate}</p>
      <p>Number of active cases of COVID-19</p>
    </div>
  ))
}

我并不完全熟悉您正在使用的数据或您希望它如何显示,但这里的一个关键考虑因素就是对象和对象数组之间的区别。您需要在代码中确定哪个。

【讨论】:

  • 对不起,我写的是案例而不是全局,但我理解你的意思。我尝试使用 {global &amp;&amp; global.confirmed.value} {global !== undefined &amp;&amp; global.confirmed.value} 但仍然给出相同的错误。顺便说一句,我也尝试过这种情况,但还是一样。
  • @poena9191:在 useState 初始化 global 时,您将其设置为对象:{}。您是否将其更改为不将其设置为任何内容?否则你会因为同样的原因得到同样的错误。空对象{} 没有名为confirmed 的属性。它基本上总是相同的模式......无论undefined是什么(无论是对象本身,对象上的属性等),您都需要在尝试使用它之前检查它是否已定义。
  • 我现在做到了,它奏效了。我认为如果数据是数组或对象,我们必须第一次定义空数组或对象。我也应该删除数组吗?
  • @poena9191:你可以定义你认为合适的初始值,没有一个规则适用于所有情况。例如,如果您有一个数组,那么您可以最初定义一个空数组,然后您的渲染器始终可以安全地迭代该数组,因为它知道它不会对空数组进行迭代。或者,如果您对某个对象有有意义的默认值,那么您可以定义该默认对象字面量。这完全取决于您希望您的初始值是什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多