React и реагировать на chartjs-2, Линейный график не отображает данные из API - PullRequest
0 голосов
/ 31 октября 2019

Я пытаюсь визуализировать линейный график с использованием response-chartjs-2. Прямо сейчас все работает нормально, когда я передаю статический реквизит компоненту Line. Но когда я получаю данные из API, устанавливаю их в переменную, а затем передаю эту переменную в качестве реквизита. Мой Линейный Компонент не выполняет повторный рендеринг с новыми данными.

Я регистрирую пропуски, передаваемые в Компонент Линии, и вижу, что он сначала прибывает как ноль, а затем я получаю хорошие данные из API. Таким образом, похоже, что Линейный Компонент не повторный рендеринг после получения реквизита? Я, вероятно, делаю это неправильно. Пожалуйста, помогите.

import React from "react";
import { Line } from "react-chartjs-2";

export default class ExpenseChart extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            marketData: [100, 200, 300],
            chartData: {
                labels: this.props.monthNames,
                datasets: [
                    {
                        backgroundColor: "rgba(142, 243, 197, 0.5)",
                        pointBackgroundColor: "#fff",
                        pointHoverBackgroundColor: '#fff',
                        pointStyle: "circle",
                        label: "Monthly Expenses",
                        borderColor: "#2be1d8",
                        borderWidth: 3,
                        borderJoinStyle: "round",
                        lineTension: 0.3,
                        fontColor: "#fff",
                        hitRadius: 5,
                        hoverRadius: 8,
                        radius: 4,
                        data: this.props.monthExpenses
                    },
                ],
            },
        };
    }

    render() {
        console.log("why no names", this.props.monthNames)
        return (
            <div className="expenseChart">
                <h2 className="expenseChart__name">{this.props.graphname}</h2>
                 <Line
                    data={this.state.chartData}
                    options={{
                        maintainAspectRatio: false,
                        responsive: true,
                        aspectRatio: 3,
                        scales: {
                            yAxes: [
                                {
                                    ticks: {
                                        display: false,
                                    },
                                },
                            ],
                        },
                        layout: {
                            padding: {
                                right: 10,
                            },
                        },
                    }}
                />
            </div>
        );
    }
}

А затем родительский компонент подключается к хранилищу с резервированием и выглядит так:

import React from "react";
import { connect } from 'react-redux';
import ExpenseChart from "../elements/ExpenseChart";
import { fetchExpenses } from '../../actions/index';

class Dashboard extends React.Component {

    componentDidMount() {
        this.props.dispatch(fetchExpenses());
    }

    render() {
        let labels = this.props.months && this.props.months;

        return (
            <main className="dashboard">
                <ExpenseChart
                    monthNames={labels}
                    monthExpenses={["123", "123", "12312", "12341", "231231", "1231", "1231"]}
                    // I am receiving monthExpenses props into the ExpenseChart component
                    // but not monthNames
                />
            </main>
        );
    }
}

const mapStateToProps = state => ({
    auth: state.app.auth,
    months: state.app.months,
});

export default connect(mapStateToProps)(Dashboard);

Я делал что-то подобное раньше, получая данные изAPI и передача его в качестве реквизита для компонента Line. Но единственная разница в том, что я использую здесь редукс. И, очевидно, на этот раз Линейный компонент не получает хорошие данные.

Ответы [ 2 ]

0 голосов
/ 01 ноября 2019

Хорошо, я решил это, просто проверив, не были ли данные, которые я получал, нулевыми, прежде чем передать их в качестве реквизита. Что я и думал, что эта строка будет делать let labels = this.props.months && this.props.months;

<main className="dashboard">
    { this.props.months != null ? <ExpenseChart monthNames={labels}/> : ''; }
</main>
0 голосов
/ 31 октября 2019

Возможно, проблема в этом componentDidMount коде.

componentDidMount() {
        this.props.dispatch(fetchExpenses());
    }

В соответствии с документами рассылка

действие (Объект †): Aпростой объект, описывающий изменения, которые имеют смысл для вашего приложения. Действия - это единственный способ получить данные в хранилище, поэтому любые данные, будь то события пользовательского интерфейса, сетевые обратные вызовы или другие источники, такие как WebSockets, должны в конечном итоге отправляться как действия. Действия должны иметь поле типа, которое указывает тип выполняемого действия. Типы могут быть определены как константы и импортированы из другого модуля. Для типа лучше использовать строки, чем для символов, потому что строки сериализуемы. За исключением типа, структура объекта действия действительно зависит от вас. Если вам интересно, обратитесь к стандартному действию Flux за рекомендациями о том, как можно построить действия.

Здесь fetchExpenses может возвращать обещание, и в этом случае вам может понадобиться

fetchExpenses().then(apiRes => dipatch({type: "ACTION_TYPE": payload: apiRes}))

Другим подходом может быть использование redux-thunk

...