Реагирует: RadarChart в Rechart отправляет ошибку, несмотря на то, что я отправил ему объект JSON

#reactjs #json #api #graph

#reactjs #json #API #График

Вопрос:

Я практикуюсь React.js и я пытаюсь отобразить диаграмму статистики покемонов, используя библиотеку Rechart.

Я объявляю состояние в виде объекта JSON в состоянии моего компонента. Затем я вызываю API, чтобы предоставить правильную статистику, соответствующую выбранному покемону в моем состоянии.

Вот моя проблема, если я помещаю жесткие значения в свой объект JSON, график отображается правильно с этими значениями при запуске приложения. Но когда значения меняются при вызове API, я получаю это предупреждение в веб-консоли, когда график пытается прочитать мои разные данные:

 Warning: Received NaN for the `x1` attribute. If this is expected, cast the value to a string.
    in line (created by PolarRadiusAxis)
    in g (created by Layer)
    in Layer (created by PolarRadiusAxis)
    in PolarRadiusAxis (at CompetenceChartPokemon.js:159)
    in svg (created by Surface)
    in Surface (created by RadarChart)
    in div (created by RadarChart)
    in RadarChart (at CompetenceChartPokemon.js:149)

Warning: Received NaN for the `y1` attribute. If this is expected, cast the value to a string.
    in line (created by PolarRadiusAxis)
    in g (created by Layer)
    in Layer (created by PolarRadiusAxis)
    in PolarRadiusAxis (at CompetenceChartPokemon.js:159)
    in svg (created by Surface)
    in Surface (created by RadarChart)
    in div (created by RadarChart)
    in RadarChart (at CompetenceChartPokemon.js:149)
             ... same error for each of the axis
 

И мой график полностью пуст, я просто вижу строки, которые представляют каждую ось графика.

Чтобы решить эту проблему, я убрал рендеринг своего графика из своей функции рендеринга, действительно, мой вызов API является асинхронным, и поэтому я думаю, что мои данные, возможно, не все были получены во время вызова для создания графика.

Но когда я отображаю свое состояние в виде JSON в веб-консоли, оно имеет правильные значения. Мне сказали, что запуск console.log() может занять много времени, и поэтому он покажет мне правильные значения в моей консоли, в то время как у более быстрого вызова graph еще не было всех этих данных, но мне это кажется странным.

Я поместил часть своего кода здесь,

 import React, { Component, Fragment } from "react";
import Axios from "axios";
import {
    Radar,
    RadarChart,
    PolarGrid,
    PolarAngleAxis,
    PolarRadiusAxis
} from "recharts";

class CompetenceChartPokemon extends Component {
    constructor(props) {
        super(props);
        this.state = {
            statistic: [
                {
                    subject: "Hp",
                    pokemonStat: 100 //I've put hard value for the 3 first stat to see if they were displaying at launch of app and they are displaying
                },
                {
                    subject: "Attack",
                    pokemonStat: 123
                },
                {
                    subject: "Defense",
                    pokemonStat: 345
                },
                {
                    subject: "Special Attack",
                    pokemonStat: 0
                },
                {
                    subject: "Special Defense",
                    pokemonStat: 0
                },
                {
                    subject: "Speed",
                    pokemonStat: 0
                }
            ],
            pokemonChosen: false,
            pokemonLoading: true,
            pokemonColorAPI: "",
            pokemonIdAPI: "",
            pokemonNameAPI: "",
        };
    }

    handlePokemonNameChange = (e) => {
        this.setState({ pokemonName: e.target.value });
        this.setState({ pokemonChosen: true });
    }

    searchPokemon = () => {
        this.setState({ pokemonLoading: true });
        Axios.get(`http://localhost:5000/getPokemon/pokemonStat/${this.state.pokemonName}`)
            .then(res => {
                if (res.status === 200 amp;amp; res != null) {
                    let copyJSONArray = this.state.statistic.slice();

                    res.data.stats.map((stat, index) => {
                        copyJSONArray[index] = stat.base_stat;
                    })

                    this.setState({ statistic: copyJSONArray });

                    this.setState({ pokemonIdAPI: res.data.id }); // here I get id of pokemon for a second API call which will give me color of pokemon (info not available in first call)

                    this.setState({ pokemonNameAPI: res.data.name });

                    console.log(res);

                    Axios.get(`http://localhost:5000/getPokemon/pokemonNameFr/${this.state.pokemonIdAPI}`)
                        .then(response => {
                            if (response.status === 200 amp;amp; response != null) {
                                this.setState({ pokemonColorAPI: response.data.color.name });
                            } else {
                                console.log('problem in second call');
                            }
                        })
                        .catch(error => {
                            console.log(error);
                        });

                    this.setState({ pokemonLoading: false });
                } else {
                    console.log('problem in first call');
                }
            })
            .catch(error => {
                console.log(error);
            });
        console.log(this.state.statistic);  //this state is filling correctly here
    }

    renderGraph() {
        let color = "";
        if (this.state.pokemonColorAPI === "black") {
            color = "#1D2525";
        }
        if (this.state.pokemonColorAPI === "blue") {
            color = "#2350B8";
        }
        if (this.state.pokemonColorAPI === "brown") {
            color = "#904F17";
        }
        if (this.state.pokemonColorAPI === "gray") {
            color = "#999999";
        }
        if (this.state.pokemonColorAPI === "green") {
            color = "#438A3B";
        }
        if (this.state.pokemonColorAPI === "pink") {
            color = "#FFB7CE";
        }
        if (this.state.pokemonColorAPI === "purple") {
            color = "#8D5E9B"
        }
        if (this.state.pokemonColorAPI === "red") {
            color = "#BB4B49";
        }
        if (this.state.pokemonColorAPI === "white") {
            color = "#F0EEFF";
        }
        if (this.state.pokemonColorAPI === "yellow") {
            color = "#FFF380";
        }

        if (this.state.pokemonNameAPI === undefined) {
            return null;
        } else {
            return (<React.Fragment>
                {console.log(this.state.statistic)}
                <RadarChart
                    cx={300}
                    cy={250}
                    outerRadius={150}
                    width={500}
                    height={500}
                    data={this.state.statistic}
                >
                    <PolarGrid />
                    <PolarAngleAxis dataKey="subject" />
                    <PolarRadiusAxis />
                    <Radar
                        name={this.state.pokemonName}
                        dataKey="pokemonStat"
                        stroke="#8884d8"
                        fill="#8884d8"
                        fillOpacity={0.6}
                    />
                </RadarChart>
            </React.Fragment>
            )
        }
    }

    render() {
        return (
            <div className="DisplayOnePokemon">
                <div className="TitleSection">
                    <h1>Pokemon Stats</h1>
                    <input type="text" onChange={this.handlePokemonNameChange} value={this.state.pokemonName} />
                    <button onClick={this.searchPokemon}>Search Pokemon stats graph</button>
                </div>
                <div className="DisplaySection">
                    {((!this.state.pokemonChosen) amp;amp; (this.state.pokemonLoading == false)) ? (
                        <h1>Please choose a Pokemon</h1>
                    ) : (
                        <div>{this.renderGraph()}</div>
                    )}
                </div>
            </div >
        );
    }
}
 

Вот ссылка на документацию графика, который я пытаюсь использовать https://recharts.org/en-US/examples/SimpleRadarChart , Я не понимаю, что я делаю не так по сравнению с примером, приведенным в документе.

Любая помощь будет с благодарностью принята 🙂

Ответ №1:

Я, наконец, заставил его работать, проблема заключалась в том, что мое объявление состояния JSON в моем конструкторе заменило его массивом и создало JSON const в моем методе renderGraph, который принимает значения из моего массива, сработало.