简体   繁体   English

为什么我无法在 React 中访问某些嵌套的 JSON 对象?

[英]Why can't I access certain nested JSON objects in React?

Im trying to practice my React skills by building a simple fetch and render app.我试图通过构建一个简单的获取和渲染应用来练习我的 React 技能。 I'm using the Scryfall api to search MTG cards.我正在使用 Scryfall api 来搜索 MTG 卡。 I'm able to render properties like the name of the card and the artist but things like the prices and images are not rendering.我能够渲染卡片名称和艺术家等属性,但无法渲染价格和图像等属性。 Here's my App.js:这是我的 App.js:

import React from "react";
import scryfall from "../api/Scryfall";
import SearchBar from "./SearchBar";
import CardInfo from "./CardInfo";

class App extends React.Component {
  state = { card: {} };

  onSearchSubmit = async (name) => {
    const response = await scryfall.get("/cards/named", {
      params: { fuzzy: name },
    });

    this.setState({ card: response.data });
    console.log(response.data);
    console.log(response.data.prices.usd);
    console.log(response.data.image_uris.normal);
  };

  render() {
    return (
      <div className="ui container" style={{ marginTop: "10px" }}>
        <SearchBar onSubmit={this.onSearchSubmit} />
        <div>Found: {this.state.card.name}</div>
        <div>Artist: {this.state.card.artist}</div>
        <div>Price: {this.state.card.prices.usd}</div>
         <img
          src={this.state.card.image_uris.normal}
          alt={this.state.card.name}
        /> 


        <CardInfo card={this.state.card} />
      </div>
    );
  }
}

export default App;

When I console.log response.data.prices.usd or respsonse.data.image_uris.normal the price and image url print respectively.当我 console.log response.data.prices.usd 或 respsonse.data.image_uris.normal 时,价格和图像 url 分别打印。 But, when I go to render them I get an error saying "can't read "usd"/"normal" of undefined".但是,当我 go 渲染它们时,我收到一条错误消息,提示“无法读取未定义的“usd”/“normal””。 What am I missing?我错过了什么?

Here's the API info:这是 API 的信息:

Content-Type: application/json; charset=utf-8

{
  "object": "card",
  "id": "bef16a71-5ed2-4f30-a844-c02a0754f679",
  "oracle_id": "09cc8709-fe10-472a-b05c-e89f3523018d",
  "multiverse_ids": [
    438576
  ],
  "mtgo_id": 65899,
  "mtgo_foil_id": 65900,
  "tcgplayer_id": 145297,
  "name": "Austere Command",
  "lang": "en",
  "released_at": "2017-11-17",
  "uri": "https://api.scryfall.com/cards/bef16a71-5ed2-4f30-a844-c02a0754f679",
  "scryfall_uri": "https://scryfall.com/card/ima/10/austere-command?utm_source=api",
  "layout": "normal",
  "highres_image": true,
  "image_uris": {
    "small": "https://img.scryfall.com/cards/small/front/b/e/bef16a71-5ed2-4f30-a844-c02a0754f679.jpg?1562853529",
    "normal": "https://img.scryfall.com/cards/normal/front/b/e/bef16a71-5ed2-4f30-a844-c02a0754f679.jpg?1562853529",
    "large": "https://img.scryfall.com/cards/large/front/b/e/bef16a71-5ed2-4f30-a844-c02a0754f679.jpg?1562853529",
    "png": "https://img.scryfall.com/cards/png/front/b/e/bef16a71-5ed2-4f30-a844-c02a0754f679.png?1562853529",
    "art_crop": "https://img.scryfall.com/cards/art_crop/front/b/e/bef16a71-5ed2-4f30-a844-c02a0754f679.jpg?1562853529",
    "border_crop": "https://img.scryfall.com/cards/border_crop/front/b/e/bef16a71-5ed2-4f30-a844-c02a0754f679.jpg?1562853529"
  },
  "mana_cost": "{4}{W}{W}",
  "cmc": 6,
  "type_line": "Sorcery",
  "oracle_text": "Choose two —\n• Destroy all artifacts.\n• Destroy all enchantments.\n• Destroy all creatures with converted mana cost 3 or less.\n• Destroy all creatures with converted mana cost 4 or greater.",
  "colors": [
    "W"
  ],
  "color_identity": [
    "W"
  ],
  "legalities": {
    "standard": "not_legal",
    "future": "not_legal",
    "historic": "not_legal",
    "pioneer": "not_legal",
    "modern": "legal",
    "legacy": "legal",
    "pauper": "not_legal",
    "vintage": "legal",
    "penny": "not_legal",
    "commander": "legal",
    "brawl": "not_legal",
    "duel": "legal",
    "oldschool": "not_legal"
  },
  "games": [
    "paper",
    "mtgo"
  ],
  "reserved": false,
  "foil": true,
  "nonfoil": true,
  "oversized": false,
  "promo": false,
  "reprint": true,
  "variation": false,
  "set": "ima",
  "set_name": "Iconic Masters",
  "set_type": "masters",
  "set_uri": "https://api.scryfall.com/sets/741bcd30-7709-4133-8919-f4b46483bed7",
  "set_search_uri": "https://api.scryfall.com/cards/search?order=set&q=e%3Aima&unique=prints",
  "scryfall_set_uri": "https://scryfall.com/sets/ima?utm_source=api",
  "rulings_uri": "https://api.scryfall.com/cards/bef16a71-5ed2-4f30-a844-c02a0754f679/rulings",
  "prints_search_uri": "https://api.scryfall.com/cards/search?order=released&q=oracleid%3A09cc8709-fe10-472a-b05c-e89f3523018d&unique=prints",
  "collector_number": "10",
  "digital": false,
  "rarity": "rare",
  "card_back_id": "0aeebaf5-8c7d-4636-9e82-8c27447861f7",
  "artist": "Anna Steinbauer",
  "artist_ids": [
    "3516496c-c279-4b56-8239-720683d03ae0"
  ],
  "illustration_id": "7c6a01f8-e1f6-4fe4-b275-b2582be98783",
  "border_color": "black",
  "frame": "2015",
  "full_art": false,
  "textless": false,
  "booster": true,
  "story_spotlight": false,
  "edhrec_rank": 191,
  "prices": {
    "usd": "8.23",
    "usd_foil": "11.01",
    "eur": "6.04",
    "tix": "0.94"
  },
  "related_uris": {
    "gatherer": "https://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=438576",
    "tcgplayer_decks": "https://decks.tcgplayer.com/magic/deck/search?contains=Austere+Command&page=1&partner=Scryfall&utm_campaign=affiliate&utm_medium=api&utm_source=scryfall",
    "edhrec": "https://edhrec.com/route/?cc=Austere+Command",
    "mtgtop8": "https://mtgtop8.com/search?MD_check=1&SB_check=1&cards=Austere+Command"
  },
  "purchase_uris": {
    "tcgplayer": "https://shop.tcgplayer.com/product/productsearch?id=145297&partner=Scryfall&utm_campaign=affiliate&utm_medium=api&utm_source=scryfall",
    "cardmarket": "https://www.cardmarket.com/en/Magic/Products/Singles/Iconic-Masters/Austere-Command?referrer=scryfall&utm_campaign=card_prices&utm_medium=text&utm_source=scryfall",
    "cardhoarder": "https://www.cardhoarder.com/cards/65899?affiliate_id=scryfall&ref=card-profile&utm_campaign=affiliate&utm_medium=card&utm_source=scryfall"
  }
}

Initially your React component state has state = { card: {} };最初你的 React 组件 state 有state = { card: {} };

But you are trying to read image_uris and name from this.state.card and they don't exist.但是您正在尝试从this.state.card中读取image_urisname ,但它们不存在。

        <div>Price: {this.state.card.prices.usd}</div>
         <img
          src={this.state.card.image_uris.normal}
          alt={this.state.card.name}
        /> 

You might want to put an if statement and not render the component if those values are undefined.如果这些值未定义,您可能想放置一个 if 语句而不渲染组件。

For example in below code, I am checking to see if this.state.card.name exists before rendering the component.例如在下面的代码中,我在渲染组件之前检查this.state.card.name是否存在。

  render() {

    if (!this.state.card.name) return null; 

    return (
      <div className="ui container" style={{ marginTop: "10px" }}>
        <SearchBar onSubmit={this.onSearchSubmit} />
        <div>Found: {this.state.card.name}</div>
        <div>Artist: {this.state.card.artist}</div>
        <div>Price: {this.state.card.prices.usd}</div>
         <img
          src={this.state.card.image_uris.normal}
          alt={this.state.card.name}
        /> 


        <CardInfo card={this.state.card} />
      </div>
    );
  }

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

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