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)
嗯.....我找到了答案...错误是不同的,但它修复了一切
将重绘道具添加到我修复的所有问题...
我将我的代码转换为 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)
嗯.....我找到了答案...错误是不同的,但它修复了一切
将重绘道具添加到我修复的所有问题...