繁体   English   中英

如何获取嵌套对象(JSON)的值以将其作为 ReactJS 中的道具传递

[英]How to get values of Nested Object (JSON) to pass it as Props in ReactJS

我正在构建一个 COVID 跟踪器网站,我在其中从 API 获取数据。

但是数据是通过 JSON 以嵌套对象模式传入的。

   "totalCandidates":"46",
   "phases":[
      {
         "phase":"Phase 3",
         "candidates":"5"
      },
      {
         "phase":"Phase 2/3",
         "candidates":"2"
      },
      {
         "phase":"Phase 2b",
         "candidates":"1"
      }
   ],

为了从 JSON 中获取totalCandidates值,我只是使用 {vaccines.totalCandidates} 这工作正常。

但是,如果我试图获取作为 Array 对象的阶段,我就会遇到问题。 请看下面的代码:

import {
  MenuItem,
  FormControl,
  Select,
  Card,
  CardContent,
} from "@material-ui/core";
import "./App.css";
import StatsComp from "./StatsComp";
import Map from "./Map";
import VaccineTable from "./VaccineTable";
//import { useHistory } from "react-router-dom";

function App() {
  const [countries, initCountries] = useState([]);
  //To Capture the selected value in dropdown
  const [country, initCountry] = useState("Universe");
  const [countryInfo, initCountryInfo] = useState([]);
  const [vaccineInfo, initVaccineInfo] = useState([]);

  //const history = useHistory();

  useEffect(() => {
    fetch("https://disease.sh/v3/covid-19/all")
      .then((response) => response.json())
      .then((data) => {
        initCountryInfo(data);
      });
  }, []);

  //hook - use async always for api calls
  useEffect(() => {
    const getCntryData = async () => {
      fetch("https://disease.sh/v3/covid-19/countries")
        .then((response) => response.json())
        .then((data) => {
          const countries = data.map((country) => ({
            name: country.country,
            value: country.countryInfo.iso2,
            flag: <img src={country.countryInfo.flag} alt="countryFlag" />,
          }));
          initCountries(countries);
        });
    };

    getCntryData();
  }, []);

  useEffect(() => {
    const getVaccineData = async () => {
      fetch("https://disease.sh/v3/covid-19/vaccine")
        .then((response) => response.json())
        .then((data) => {
          initVaccineInfo(data);
        });
    };
    getVaccineData();
  }, []);

  //Listener
  const listenCountrySelect = async (event) => {
    const countryValue = event.target.value;
    initCountry(countryValue);

    const url =
      countryValue === "Universe"
        ? "https://disease.sh/v3/covid-19/all"
        : `https://disease.sh/v3/covid-19/countries/${countryValue}`;

    await fetch(url)
      .then((response) => response.json())
      .then((data) => {
        initCountry(countryValue);
        initCountryInfo(data);
      });
  };

  console.log("URL :::: ", countryInfo);
  console.log("Vcccinee :::", vaccineInfo);
  return (
    <div className="app">
      <div className="HC__left">
        <div className="HC__Header">
          {/*Title of the Website*/}
          <h1>Honest Covid</h1>
        </div>

        {/* Countries Dropdown for viewing information */}
        <FormControl className="HC__countries__dropdown">
          <Select
            variant="outlined"
            value={country}
            onChange={listenCountrySelect}
            className="HC__select"
          >
            {/*This will give all countries aggregate value*/}
            <MenuItem value="Universe" className="HC__menuitem">
              Universe
            </MenuItem>

            {/* Here we map through all countries and display a menuitem individually*/}
            {countries.map((country) => (
              <MenuItem value={country.value} className="HC__menuitem">
                {" "}
                {country.flag} {country.name}{" "}
              </MenuItem>
            ))}
          </Select>
        </FormControl>

        <div className="HC__statistics">
          <StatsComp
            title="Recovered"
            cases={countryInfo.todayRecovered}
            total={countryInfo.recovered}
          />
          <StatsComp
            title="Cases"
            cases={countryInfo.todayCases}
            total={countryInfo.cases}
          />
          <StatsComp
            title="Deaths"
            cases={countryInfo.todayDeaths}
            total={countryInfo.deaths}
          />
        </div>

        <Map />
      </div>

      {/* Here comes vaccine status and video*/}
      <Card className="HC__right">
        <CardContent>
          <h3> Vaccine Status</h3>
          <VaccineTable vaccines={vaccineInfo} />
          <h3> Good Practices during COVID</h3>
        </CardContent>
      </Card>
    </div>
  );
}

export default App;

以上是我的 App.js,我在其中获取数据并将其设置为vaccineInfo 状态。 然后将该对象作为 Prop 传递给另一个组件 VaccineTable.js。

import React from "react";
import "./VaccineTable.css";

function VaccineTable({vaccines}) {
  return (
    <div className="HC__vaccinetable">
      {vaccines.map(({ phases }) => (
        <tr>
          <td>{phases}</td>
          <td>
            <strong>{phases}</strong>
          </td>
        </tr>
      ))}
    </div>
  );
}

export default VaccineTable;

但为此,我收到一个错误:

“类型错误:疫苗.map 不是函数”

问题是什么?

谢谢。

问题是https://disease.sh/v3/covid-19/vaccine返回一个object 您需要访问data属性,它是一个数组。 IE

  fetch("https://disease.sh/v3/covid-19/vaccine")
    .then((response) => response.json())
    .then(({data}) => { <---- destructure the 'data' property here, and use that
      initVaccineInfo(data);
    });

数据是一个对象。 您需要使用 data.phases 来提取数组并保存在 initVaccineInfo 中

useEffect(() => {
    const getVaccineData = async () => {
      fetch("https://disease.sh/v3/covid-19/vaccine")
        .then((response) => response.json())
        .then((data) => {
          initVaccineInfo(data.phases);
        });
    };
    getVaccineData();
  }, []);

你在这里得到一个数组吗console.log("Vcccinee :::", vaccineInfo); ? 如果是,那么把检查内部VaccineTable.js前vaccines.mapvaccine.length && vaccines.map ,因为通过道具是异步的。

如果没有,则在 useEffect 下方放置一个控制台并检查您正在获取的数据。

const getVaccineData = async () => {
      fetch("https://disease.sh/v3/covid-19/vaccine")
        .then((response) => response.json())
        .then((data) => {
          initVaccineInfo(data.phases);
        });
    };
    getVaccineData();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM