作者:阮琳芷信玲俊岳 | 来源:互联网 | 2022-12-23 19:38
我有一个带有子图表组件的主要组件。连接到Websocket时,主要组件将更新子图表组件的状态。但是,这不会重绘。但是,当我单击图表时,将显示标签,而当我再次单击时,值将与标签一起显示。
Main.js:
import IO from 'socket.io-client';
import React from "react";
import { Switch, Route } from 'react-router-dom';
import { Chart } from "./Chart";
let ftse100Tickers = require('./ftse_100_tickers.json');
let randomInt = Math.floor(Math.random() * ftse100Tickers.tickers.length);
/**
* Main application component which contains
*/
export class Main extends React.Component {
componentWillMount() {
this.socket = IO(location.protocol + "//" + document.domain + ":" + location.port);
this.socket.on("connect", (() => this.connect()));
this.socket.on("disconnect", (() => this.disconnect()));
this.socket.on("initial data", ((data) => this.createInitialChart(data)))
}
connect(){
this.setState({status: 'connected'});
this.socket.emit("get initial data", this.state.ticker);
}
disconnect(){
this.setState({status: 'disconnected'})
}
createInitialChart(data){
let tempErrorChart= this.state.errorChart;
for (let row of data){
tempErrorChart.labels.push(row.time_stamp);
tempErrorChart.datasets[0].data.push(row.error);
}
this.setState({errorChart: tempErrorChart});
}
constructor(props){
super(props);
this.state = {
errorChart: {
labels: [],
datasets: [
{
label: 'Error',
data: [],
},
]
},
status: 'disconnected',
ticker : ftse100Tickers.tickers[randomInt],
twitter : ftse100Tickers.twitter[randomInt]
}
}
render() {
return (
)
}
}
图表组件是这样的:
Chart.js
import { Line } from "react-chartjs-2"
import React from "react";
/*
* General charting component used for rendering charts
*/
export class Chart extends React.Component {
render() {
return (
)
}
}
Dan Macák..
5
我看到一个问题,那就是在你不改变对象的引用this.state.errorChart
在errorChart更新打电话之前setState
。即使你把它的属性的新项目,对象,甚至内部数组引用不改变,如果行分量做一些道具上是否应该重新呈现自身或不检查,它的数字通过接收依然没有什么相同的参考已经更改,因此无需重新渲染。
现在,这只是我的假设,但是无论哪种方式,当这些对象即将被修改时,始终在创建新对象的同时创建新状态是一个好习惯。这允许在shouldComponentUpdate
方法中或使用PureComponent
它们时进行快速的对象(状态)引用比较,从而可以更轻松,更高效地确定是否重新渲染组件。在另一方面,如果你想使用相同的引用仍然,你就必须实现旧的深比较新的状态,这绝对是更加昂贵,并且从长远来看非常脆弱。
例如如何正确地更新状态如下:
createInitialChart(data) {
const errorChart = this.state.errorChart
const newErrorChart = {
...errorChart
}
newErrorChart.labels = [...errorChart.labels, data.map(row => row.time_stamp)]
newErrorChart.datasets[0].data = [
...errorChart.datasets[0].data,
data.map(row => row.error)
]
this.setState({ errorChart: newErrorChart })
}
编辑:
通过查看组件的shouldComponentUpdate
实现-ChartComponent,可以清楚地看到,关于如何使Line rerender 有多个选项,例如。通过给redraw={true}
道具的线组件。上述过程通常仍然是确保虽然重新呈现最安全的方式。
1> Dan Macák..:
我看到一个问题,那就是在你不改变对象的引用this.state.errorChart
在errorChart更新打电话之前setState
。即使你把它的属性的新项目,对象,甚至内部数组引用不改变,如果行分量做一些道具上是否应该重新呈现自身或不检查,它的数字通过接收依然没有什么相同的参考已经更改,因此无需重新渲染。
现在,这只是我的假设,但是无论哪种方式,当这些对象即将被修改时,始终在创建新对象的同时创建新状态是一个好习惯。这允许在shouldComponentUpdate
方法中或使用PureComponent
它们时进行快速的对象(状态)引用比较,从而可以更轻松,更高效地确定是否重新渲染组件。在另一方面,如果你想使用相同的引用仍然,你就必须实现旧的深比较新的状态,这绝对是更加昂贵,并且从长远来看非常脆弱。
例如如何正确地更新状态如下:
createInitialChart(data) {
const errorChart = this.state.errorChart
const newErrorChart = {
...errorChart
}
newErrorChart.labels = [...errorChart.labels, data.map(row => row.time_stamp)]
newErrorChart.datasets[0].data = [
...errorChart.datasets[0].data,
data.map(row => row.error)
]
this.setState({ errorChart: newErrorChart })
}
编辑:
通过查看组件的shouldComponentUpdate
实现-ChartComponent,可以清楚地看到,关于如何使Line rerender 有多个选项,例如。通过给redraw={true}
道具的线组件。上述过程通常仍然是确保虽然重新呈现最安全的方式。