从 API 检索数据时反应函数中的未定义参数

Undefined parameter in react function when retrieving data from API

我正在尝试从 API 中检索数据,但它需要一个加密的名称,我从另一个 API 调用中收到该名称。所以,我试图使用第一个 API 中的数据来检索第二个 API 中的数据,但是当我尝试传递适当的数据时,它说它是未定义的,当我甚至可以打印出来。

import { useState, useEffect } from "react";
import { Typography, Row, Col, Statistic } from "antd";
import { Link } from "react-router-dom";
import axios from "axios";

const { Title } = Typography;

const Homepage = () => {
  const [searchText, setSearchText] = useState("");
  const [playerData, setPlayerData] = useState({});
  const [playerStats, setPlayerStats] = useState({});

  const API_KEY = "MyprivateAPIKEY";

  function searchForPlayer(event) {
    var APICallSummoner =
      "https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/" +
      searchText +
      "?api_key=" +
      API_KEY;

    axios
      .get(APICallSummoner)
      .then(function (response) {
        setPlayerData(response.data);
      })
      .catch(function (error) {
        console.log(error);
      });
  }

  function searchPlayerData(id) {
    var API =
      "https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/" +
      id +
      "?api_key=" +
      API_KEY;
    axios
      .get(API)
      .then(function (response) {
        setPlayerStats(response.data);
      })
      .catch(function (error) {
        console.log(error);
      });
  }

  return (
    <>
      <Title level={2} className='heading'>
        LoLTracker
      </Title>

      <input
        type='text'
        onChange={(e) => setSearchText(e.target.value)}></input>
      <button
        onClick={(e) => {
          searchForPlayer(e);
          var a = playerData.id;
          console.log(a);
          searchPlayerData(a);
        }}>
        Search Player
      </button>

      {JSON.stringify(playerData) != "{}" ? (
        <>
          <p>{playerData.name}</p>
          <img
            width='100'
            height='100'
            src={
              "http://ddragon.leagueoflegends.com/cdn/12.3.1/img/profileicon/" +
              playerData.profileIconId +
              ".png"
            }></img>
          <p>Summoner Level: {playerData.summonerLevel} </p>
        </>
      ) : (
        <>
          <p>No Player Data</p>
        </>
      )}

      <Row>
        <Col span={12}>
          <Statistic title='Total Games Played' value={playerStats.wins} />
        </Col>
        <Col span={12}>
          <Statistic title='Ranked Solo Duo Games' value='5' />
        </Col>
        <Col span={12}>
          <Statistic title='Wins' value='5' />
        </Col>
        <Col span={12}>
          <Statistic title='Losses' value='5' />
        </Col>
      </Row>
    </>
  );
};

export default Homepage;

在我的 onClick() 函数中,我从 searchForPlayer 获得了所需的信息,但我无法将数据传递到我的 searchForPlayer 函数。请帮忙

在 React 中,状态更新本质上是异步的,因此您不能期望在调用 state update(setState) 后立即在下一行更新状态值。
在您单击按钮的情况下,您正在这样做 -

<button
    onClick={(e) => {
        // this will change state value for playerData
        searchForPlayer(e);
        // but here on next line you cannot access updated value
        // because searchForPlayer will not run synchronously
        var a = playerData.id;
        console.log(a); // so you will mostly get undefined here
        searchPlayerData(a);
    }}>
    Search Player
</button>
  1. 要解决此问题,您需要使用 useEffectplayerData 的依赖数组,就像这样 -
React.useEffect(() => {
    if(playerData.id){
        //call next function or api here
    }
}, [playerData])

以上 useEffect 将在您的 playerData 更改时被调用。所以在这里,你可以调用任何需要状态 playerData 的东西。

  1. 或者,如果您只需要在 searchForPlayer 之后调用 searchPlayerData,则无需使用 state 存储 playerData,然后将其传递给 searchPlayerData你可以在searchForPlayer里直接调用.then里面的searchPlayerData,看下面的代码-
function searchForPlayer(event) {
    var APICallSummoner =
        "https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/" +
        searchText +
        "?api_key=" +
        API_KEY;

    axios
        .get(APICallSummoner)
        .then(function (response) {
            // you do not need to set below state value
            // if you are not going to use it other than calling next api
            setPlayerData(response.data);
            if(response.data){
                //calling next function here
                searchPlayerData(response.data.id);
            }
        })
        .catch(function (error) {
            console.log(error);
        });
}