Компонент класса React Chart Js

Я преобразовал свой код в компонент класса, и все начало ломаться. Я понял, где он ломается, но я не могу понять, почему он ломается. Думаете, вы, ребята, можете мне помочь?

Что происходит, так это то, что когда я меняю имя в этом поле ввода (раздел с красной стрелкой), компонентDidMount срабатывает и дает мне эту ошибку.

Поэтому я сузил проблему до того, когда я setState и делаю данные: chartData в componentDidMount. Если этот фрагмент кода закомментирован, он работает, иначе нет.

Chartjs может принимать пустой объект, поэтому я выполняю проверку только для обновления значения, если есть что-то, что можно обновить. Но да, я действительно не знаю, что не так и как это исправить...

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

Просмотр диаграммы введите здесь описание изображения

введите здесь описание изображения

До изменения

import React, {useEffect, useState} from 'react'
import {Redirect} from "react-router-dom";
import {connect} from 'react-redux'
import {Line} from "react-chartjs-2";
import moment from "moment";
import "./DeviceDetails.css"
import axios from "axios";

const DeviceDetails = (props) => {
    const {auth, device, sensorData,deviceName} = props
    const [chartData, setChartData] = useState({})
    const today = moment().format().split("T")[0]
    const localTime = moment(device.dateTime).format("DD/MM/YYYY HH:mm").toString()

    
    useEffect(() => {
        let chartData = {}

        if (sensorData) {
            chartData = sensorData.map(data => {
                const container = {};
                container.x = moment(data.dateTime)
                container.y = data.soilMoisturePercent
                return container
            })
        }


        const chart = () => {
            setChartData({
                labels: [moment().startOf('day'), moment().endOf('day')],
                datasets: [
                    {
                        label: "Moisture Levels",
                        data: chartData,
                        backgroundColor: ['rgba(75,192,192,0.6)'],
                        borderWidth: 4
                    }
                ],
            })
        }

        chart()
    }, [sensorData]);

    const options = {...}

    if (!auth.uid) {
        return <Redirect to="/signin"/>
    } else {
        return (
            <div className="fitting dashboard-container section">
                <div className="device-details z-depth-0">
                    <div className="card-content">
                        <p className="card-title"> Name - {deviceName} </p>
                        <p> Date/Time - {localTime} </p>
                        <p> Battery Percent - {device.battery} </p>
                        <p> Moisture Percent - {device.soilMoisturePercent} </p>
                    </div>
                    <div className="card-action grey lighten-4 grey-text">
                        <input type="date" defaultValue={today} max={today} onChange={(event => handleChange(event.target.value))}/>
                        <Line data={chartData} options={options}/>
                    </div>
                </div>
            </div>
        )
    }
}

const mapStateToProps = (state, ownProps) => {
    const id = ownProps.match.params.id;
    const devices = state.device.devices;
    const sensors = state.device.sensorData;
    const device = devices ? devices[id] : null
    const deviceName = state.auth.user.devices[id].Value
    const sensorData = sensors ? sensors[id] : null
    return {
        auth: state.firebase.auth,
        device: device,
        sensorData: sensorData,
        deviceName: deviceName,
    }
}

export default connect(mapStateToProps)(DeviceDetails)

После изменения компонента класса

import React, {Component} from 'react'
import {Redirect} from "react-router-dom";
import {connect} from 'react-redux'
import {Line} from "react-chartjs-2";
import moment from "moment";
import "./DeviceDetails.css"
import axios from "axios";
import {updateDeviceName} from "../../store/Actions/AuthActions";

class DeviceDetails extends Component {
    constructor(props) {
        super(props);
        this.state = {
            chartData: {},
            options: {...},
            devName: this.props.deviceName,
            deviceId: this.props.device.deviceId
        }
    }

    componentDidMount = () => {
        const {sensorData} = this.props

        let chartData = {}

        if (sensorData) {
            chartData = sensorData.map(data => {
                const container = {};
                container.x = moment(data.dateTime)
                container.y = data.soilMoisturePercent
                return container
            })
        }

        this.setState({
            chartData: {
                labels: [moment().startOf('day'), moment().endOf('day')],
                datasets: [
                    {
                        label: "Moisture Levels",
                        data: chartData,
                        backgroundColor: ['rgba(75,192,192,0.6)'],
                        borderWidth: 4
                    }
                ],
            }
        })
    }

    handleNameChange = (event) => {
        this.setState({
            devName: event.target.value
        })
    }

    updateDeviceName = () => {
        this.props.updateDeviceName(this.state)
    }

    render() {
        const {auth, device} = this.props
        const today = moment().format().split("T")[0]
        const localTime = moment(device.dateTime).format("DD/MM/YYYY HH:mm").toString()

        if (!auth.uid) {
            return <Redirect to="/signin"/>
        } else {
            return (
                <form>
                    <div className="fitting dashboard-container section">
                        <div className="device-details z-depth-0">
                            <div className="card-content">
                                <input type="text" id="devName" value={this.state.devName}
                                       onChange={this.handleNameChange} onBlur={this.updateDeviceName}/>
                                <p> Date/Time - {localTime} </p>
                                <p> Battery Percent - {device.battery} </p>
                                <p> Moisture Percent - {device.soilMoisturePercent} </p>
                            </div>
                            <div className="card-action grey lighten-4 grey-text">
                                <input type="date" defaultValue={today} max={today}
                                       onChange={(event => this.handleChange(event.target.value))}/>
                                <Line data={this.state.chartData} options={this.state.options}/>
                            </div>
                        </div>
                    </div>
                </form>
            )
        }
    }
}

const mapStateToProps = (state, ownProps) => {
    const id = ownProps.match.params.id;
    const devices = state.device.devices;
    const sensors = state.device.sensorData;
    const device = devices ? devices[id] : null
    const deviceName = state.auth.user.devices[id].Value.toString()
    const sensorData = sensors ? sensors[id] : null
    return {
        auth: state.firebase.auth,
        device: device,
        sensorData: sensorData,
        deviceName: deviceName,
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        updateDeviceName: (device) => dispatch(updateDeviceName(device))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(DeviceDetails)


person astronik    schedule 05.10.2020    source источник


Ответы (1)


Ну..... Нашел ответ... Ошибки разные но все исправил

ошибка обновления состояния react-chartjs

Добавление реквизита перерисовки к моему исправлению всех проблем...

person astronik    schedule 05.10.2020