React Chart Js Class 组件

React Chart Js Class Component

我将我的代码转换为 class 组件,然后事情开始崩溃。我知道它在哪里坏了,但我似乎无法弄清楚它为什么坏了。觉得你们可以帮助我吗?

当我更改此输入字段(红色箭头部分)中的名称时,componentDidMount 触发并给我这个错误。

所以我将问题缩小到我在 componentDidMount 中设置状态和执行数据:图表数据时的问题。如果那段代码被注释掉,它就可以工作,否则就不会。

Chartjs 可以接受一个空对象,因此为什么我要进行检查以仅在有更新对象时才更新值。但是,是的,我真的不知道出了什么问题或如何解决...

在我将它变成 class 组件之前,我的所有代码都在工作,我会把它改回来,但是顶部的输入字段,我之前在动态更新它时遇到了麻烦。我也会展示我之前和之后的代码。顺便说一句,我确实删除了一些函数,以免让代码变得如此冗长,我可以验证这些函数没有破坏我的代码

图表视图

变更前

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)

更改为 Class 组件后

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)

嗯.....我找到了答案...错误是不同的,但它修复了一切

将重绘道具添加到我修复的所有问题...