Reputation: 3
I want to display the data I get from the websocket. The render funtion gets called when the isn't already there. I tried to update it with this.state when the websocket has sent the data but it is not working. I'm using recharts to display the BarChart and in data I need the value from the WebSocket.
index.js
import _ from 'lodash';
import style from './style.css';
import React, { PureComponent } from 'react';
import ReactDOM from 'react-dom';
import {
BarChart, Bar, Cell, XAxis, YAxis, CartesianGrid, Tooltip, Legend, LabelList, Label
} from 'recharts';
var data;
class Example extends React.Component {
constructor(props) {
super(props);
//setting a default value
this.state = { data: [{time:23.30,value:288.65},{Energy:0,value:0.0}] };
}
//componentDidMount() {
//this.state = { data: data };
//console.log("compMount");
//}
render() {
//verbinde();
var connection = new WebSocket('ws://next-gen-rz.hs-harz.de:8080/fhem_prototyp2/Test');
connection.onopen = function () {
connection.send('day');
console.log("gesendet: day");
};
// Log errors
connection.onerror = function (error) {
console.log('WebSocket Error ' + error);
};
// Log messages from the server
connection.onmessage = function (e) {
console.log('Server: ' + e.data);
this.setState = {data: e.data };
};
return (
<BarChart
width={800}
height={500}
data={this.state.data}
margin={{
top: 5, right: 30, left: 20, bottom: 5,
}}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="time" tick={{ fill: 'white'}}/>
<YAxis tick={{ fill: 'white' }} label={{ value: 'kWh', angle: -90, position: 'insideLeft' }}>
</YAxis>
<Bar name="Wochenverbrauch" dataKey="value" fill="#f59f4a" >
<LabelList dataKey="value" position="top" fill='white'/>
</Bar>
</BarChart>
);
}
}
ReactDOM.render(<Example />, document.getElementById("left"));
Upvotes: 0
Views: 3504
Reputation: 18083
You should open the websocket connection only once in the componentDidMount
method lifecycle.
To update the state, you should call the setState function
You also need to close the websocket connection in the componentWillUnmount
method to avoid memory leaks
class Example extends React.Component {
constructor(props) {
super(props);
//setting a default value
this.state = { data: [{time:23.30,value:288.65},{Energy:0,value:0.0}] };
}
componentDidMount() {
const that = this;
that.connection = new WebSocket(
'ws://next-gen-rz.hs-harz.de:8080/fhem_prototyp2/Test'
);
that.connection.onopen = function () {
that.connection.send('day');
};
// Log errors
that.connection.onerror = function (error) {
console.log('WebSocket Error ' + error);
};
// Log messages from the server
that.connection.onmessage = function(e) {
console.log('Server: ' + e.data);
that.setState({data: e.data });
};
}
componentWillUnmount() {
this.connection && this.connection.close();
}
render() {
return (
<BarChart
width={800}
height={500}
data={this.state.data}
margin={{top: 5, right: 30, left: 20, bottom: 5}}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="time" tick={{ fill: 'white'}}/>
<YAxis
tick={{ fill: 'white' }}
label={{ value: 'kWh', angle: -90, position: 'insideLeft' }}
/>
<Bar name="Wochenverbrauch" dataKey="value" fill="#f59f4a" >
<LabelList dataKey="value" position="top" fill='white'/>
</Bar>
</BarChart>
);
}
}
Upvotes: 2
Reputation: 14589
You can't update by mutating the state, you need to call the function:
this.setState(newState)
and provide the newState object. See https://reactjs.org/docs/react-component.html#setstate
Also, you can't set the state in the render function, you need to get the data in componentDidMount
, for example, and then set the state there.
Upvotes: 1