TypeError:无法读取未定义的属性“ CoinName”

时间:2019-07-19 12:48:55

标签: reactjs

我为我的应用提供了这两个版本,并且为每个错误添加了代码。我似乎无法弄清楚如何解决这两个错误。遇到这两个错误,我的应用程序将无法运行。尽快提供任何帮助都是很棒的。

TypeError:无法读取未定义的属性'CoinName'

import React from "react";
import styled from "styled-components";
import { Tile } from "../Shared/Tile";
import { AppContext } from "../App/AppProvider";
import CoinImage from "../Shared/CoinImage";

export default function() {
  return (
    <AppContext.Consumer>
      {({ currentFavorite, coinList }) => (
        <Tile>
          <SpotlightName> {coinList[currentFavorite].CoinName} </SpotlightName>
          <CoinImage spotlight coin={coinList[currentFavorite]} />
        </Tile>
      )}
    </AppContext.Consumer>
  );
}

TypeError:无法读取未定义的属性“ map”

import React from "react";
import styled from "styled-components";
import { AppContext } from "../App/AppProvider";
import PriceTile from "./PriceTile";

export default function() {
  return (
    <AppContext.Consumer>
      {({ prices }) => (
        <PriceGrid>
          {Array.isArray(prices) && prices.map((price, index) => (
            <PriceTile key={`priceTile-${index}`} index={index} price={price} />
          ))}

        </PriceGrid>
      )}
    </AppContext.Consumer>
  );
}

下面的AppProvider文件

import React from "react";
import _ from "lodash";
import { async } from "q";
import moment from "moment";

// API call to CryptoCompare
const cc = require("cryptocompare");
// Set the Maximum amount of favorite coins
const MAX_FAVORITES = 10;
// used for historical function below
const TIME_UNITS = 10;

export const AppContext = React.createContext();

export class AppProvider extends React.Component {
  constructor(props) {
    super(props);
    // Default states
    this.state = {
      page: "clocks",
      favorites: ["BTC", "LTC", "ETH", "DASH"],
      timeInterval: "[this.state.timeInterval]",
      ...this.savedSettings(),
      setPage: this.setPage,
      addCoin: this.addCoin,
      removeCoin: this.removeCoin,
      isInFavorites: this.isInFavorites,
      confirmFavorites: this.confirmFavorites,
      setCurrentFavorite: this.setCurrentFavorite,
      setFilteredCoins: this.setFilteredCoins,
      changeChartSelect: this.changeChartSelect
    };
  }
  // Whenever we mount this whole app component, we fetch the coins and thier prices
  componentDidMount = () => {
    this.fetchCoins();
    this.fetchPrices();
    this.fetchHistorical();
  };

  fetchCoins = async () => {
    let coinList = (await cc.coinList()).Data;
    this.setState({ coinList });
  };

  // async function
  fetchPrices = async () => {
    if (this.state.firstVisit) return;
    let prices = await this.prices();
    this.setState({ prices });
  };

  fetchHistorical = async () => {
    if (this.state.firstVisit) return;
    let results = await this.historical();
    let historical = [
      {
        name: this.state.currentFavorite,
        data: results.map((ticker, index) => [
          moment()
            .subtract({ [this.state.timeInterval]: TIME_UNITS - index })
            .valueOf(),
          ticker.USD
        ])
      }
    ];
    this.setState({ historical });
  };

  // this function supports fetchPrices above
  prices = async () => {
    let returnData = [];
    for (let i = 0; i < this.state.favorites.length; i++) {
      try {
        let priceData = await cc.priceFull(this.state.favorites[i], "USD");
        returnData.push(priceData);
      } catch (e) {
        console.warn("Fetch price error: ", e);
      }
    }
    return returnData;
  };

  // this function supports fetchHistorical above
  historical = () => {
    let promises = [];
    for (let units = TIME_UNITS; units > 0; units--) {
      promises.push(
        cc.priceHistorical(
          this.state.currentFavorite,
          ["USD"],
          moment()
            .subtract({ [this.state.timeInterval]: units })
            .toDate()
        )
      );
    }
    return Promise.all(promises);
  };

  addCoin = key => {
    let favorites = [...this.state.favorites];
    if (favorites.length < MAX_FAVORITES) {
      favorites.push(key);
      this.setState({ favorites });
    }
  };

  removeCoin = key => {
    let favorites = [...this.state.favorites];
    this.setState({ favorites: _.pull(favorites, key) });
  };

  isInFavorites = key => _.includes(this.state.favorites, key);

  confirmFavorites = () => {
    let currentFavorite = this.state.favorites[0];
    this.setState(
      {
        firstVisit: false,
        page: "clocks",
        currentFavorite,
        prices: null,
        historical: null
      },
      () => {
        this.fetchPrices();
        this.fetchHistorical();
      }
    );
    localStorage.setItem(
      "blockclockDash",
      JSON.stringify({
        favorites: this.state.favorites,
        currentFavorite
      })
    );
  };

  // Set the localStorage to be a stringified object of our current value MERGED with our current Favorite selection
  setCurrentFavorite = sym => {
    this.setState(
      {
        currentFavorite: sym,
        historical: null
      },
      this.fetchHistorical
    );
    localStorage.setItem(
      "blockclockDash",
      JSON.stringify({
        ...JSON.parse(localStorage.getItem("blockclockDash")),
        currentFavorite: sym
      })
    );
  };

  savedSettings() {
    let blockclockDashData = JSON.parse(localStorage.getItem("blockclockDash"));
    if (!blockclockDashData) {
      return { page: "coin select", firstVisit: true };
    }
    let { favorites, currentFavorite } = blockclockDashData;
    return { favorites, currentFavorite };
  }

  setPage = page =>
    this.setState({
      page
    });

  setFilteredCoins = filteredCoins => this.setState({ filteredCoins });

  changeChartSelect = value => {
    this.setState(
      { timeInterval: value, historical: null },
      this.fetchHistorical
    );
  };

  render() {
    return (
      <AppContext.Provider value={this.state}>
        {this.props.children}
      </AppContext.Provider>
    );
  }
}

1 个答案:

答案 0 :(得分:0)

一种避免该错误的幼稚方法是首先检查两个值是否不是null

export default function() {
  return (
    <AppContext.Consumer>
      {({ currentFavorite, coinList }) => (
       (coinList && currentFavorite) ?
       <Tile>
          <SpotlightName> {coinList[currentFavorite].CoinName} </SpotlightName>
          <CoinImage spotlight coin={coinList[currentFavorite]} />
        </Tile>
       : <div>Loading... </div>
      )
      }
    </AppContext.Consumer>
  );
}