【问题标题】:Why does my API call function return an undefined object?为什么我的 API 调用函数返回一个未定义的对象?
【发布时间】:2020-08-28 04:52:47
【问题描述】:

我在 ReactJS 中有这个组件,它在英雄联盟(视频游戏)中进行 API 调用。我正在尝试绘制用户“过去 20 场比赛中使用次数最多的英雄”的图表。但是,我需要检索所有英雄 ID 和英雄名称的对象。此问题发生在 ma​​tchHeroes(championObj, ChampionList) 函数 - 第 76 行

在 chrome 开发者工具中,我在第 77 行得到一个来自 ChartData.js 的对象 https://i.stack.imgur.com/wGlcH.jpg

对象显示冠军ID作为键,冠军名称作为值 https://i.stack.imgur.com/aenCM.jpg

当我尝试 console.log(championObj[876]) 时,它应该打印“Lillia”,但它打印的是 undefined https://i.stack.imgur.com/Nb5Av.jpg

import React, { Component } from 'react'
import { Bar
    // ,Line
    // ,Pie
} from 'react-chartjs-2'

class ChartData extends Component {
    constructor(props) {
        super(props)
        this.state = {
            error: null,
            isLoaded: false,
            accountId: props.accountId,
            matchHistory: [],
            chartData: {},
            championLibrary: {},
            championList:[]
        }
    }

    componentDidMount = () => {
        this.getMatchHistory();
    }

    getMatchHistory = () => {
        let championList = [];
        const proxyurl = "https://mysterious-wave-96239.herokuapp.com/";
        const url = "https://na1.api.riotgames.com/lol/match/v4/matchlists/by-account/" + this.state.accountId + "?endIndex=20&api_key=" +process.env.REACT_APP_SECRET_KEY;
        fetch(proxyurl + url)
        .then(res => res.json())
        .then(
            (result) => {
                this.setState({
                    isLoaded: true,
                    matchHistory: Object.entries(result.matches).map(([x,championId]) => {
                      return championList.push(championId.champion.toString())
                    })
                },
                this.getHeroJson(championList)
                )
                this.setState({
                  championList: championList
                })
            },
            (error) => {
                this.setState({
                    isLoaded: true,
              error: {
                  message: "Error - Something went wrong!"
                  }
                });
            }
        )
    }

    getHeroJson = (championList) => {
      let championObj = {}
      const proxyurl = "https://mysterious-wave-96239.herokuapp.com/";
        const url = "https://ddragon.leagueoflegends.com/cdn/10.15.1/data/en_US/champion.json";
          fetch(proxyurl + url) 
            .then(response => response.json())
            .then(contents => {
                  Object.entries(contents.data).map(([key, value]) => 
                    championObj[value.key] = [value.name].toString()
                  ) 
            })
            .catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))

            this.setState({
              championLibrary: championObj
            })
            // console.log(this.state.championLibrary)
            this.matchHeroes(championObj, championList)
    }

    matchHeroes = (championObj, championList) => {
      console.log(championObj)
      console.log(championObj[876])
      Object.entries(championObj).map(([name, loader])=> {
        console.log(name, loader)
      })
      this.getChartData();
    }


    getChartData = () => {
        let championCount = {
          'Zed': 8,
          'Akali': 2,
          'Nunu' : 4,
          'Luxe' : 4,
          'Amumu': 1,
          'Fiona': 1,
          'Yassuo': 3,
        }


        this.setState({
          chartData:{
            labels: Object.keys(championCount),
            datasets:[
              {
                label:'Population',
                data: Object.values(championCount),
                backgroundColor:[
                  'rgba(255, 99, 132, 0.6)',
                  'rgba(54, 162, 235, 0.6)',
                  'rgba(255, 206, 86, 0.6)',
                  'rgba(75, 192, 192, 0.6)',
                  'rgba(153, 102, 255, 0.6)',
                  'rgba(255, 159, 64, 0.6)',
                  'rgba(255, 99, 132, 0.6)'
                ]
              }
            ]
          }
        });
      }

    static defaultProps = {
        displayTitle: true,
        displayLegends: true,
        legendPosition: 'right'
    }
    
    render () {
        return (
            <div className="chart">
                <Bar
                    data={this.state.chartData}
                    options={{
                        scales: {
                            yAxes: [{
                              ticks: {
                                beginAtZero: true
                              }
                            }]
                          },
                        title: {
                        display: this.props.displayTitle,
                        text: "Most played champions in 20 games",
                        fontSize: 25
                    },
                    legend: {
                    display: this.props.displayLegend,
                    position: this.props.legendPosition
                    }
                }}
                />
            </div>
        )
    }
}
export default ChartData

【问题讨论】:

  • 当您在第二个then 中登录result 时会得到什么?
  • @DedaDev,根据这张图片 - i.stack.imgur.com/aenCM.jpg - 如果我使用 console.log(championObj[2]),我应该得到“Olaf”,但它返回 undefined
  • console.log(championObj) 显示整个对象,但您无法访问特定的道具,如championObj[2] ?
  • @DedaDev 是的,我也无法访问 ChampionObj 中的任何其他键
  • 如果你把this.setState({championLibrary: championObj})注释掉?

标签: javascript reactjs google-chrome-devtools


【解决方案1】:

这是工作的代码发送框,在异步调用完成之前调用函数存在错误。

https://codesandbox.io/s/sad-rgb-bux05?file=/src/App.js

【讨论】:

  • 再次感谢您帮我解决这个问题,感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2014-06-04
  • 1970-01-01
  • 2019-01-21
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多