问题描述
我将代码转换为类组件,事情开始崩溃。我想出了它在哪里破裂,但我似乎无法弄清楚为什么它在破裂。认为你们可以帮助我吗?
会发生什么情况,当我在此输入字段(红色箭头部分)中更改名称时,componentDidMount会触发并给出此错误。
因此,我将问题范围缩小到setState并执行数据:componentDidMount中的chartData。如果该段代码已被注释掉,则它可以正常工作,否则就不会。
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,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'),}
})
}
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,}
}
const mapdispatchToProps = (dispatch) => {
return {
updateDeviceName: (device) => dispatch(updateDeviceName(device))
}
}
export default connect(mapStatetoProps,mapdispatchToProps)(DeviceDetails)