Как обновить значение в render () в React? - PullRequest
0 голосов
/ 18 мая 2019

Я хочу отобразить данные, которые я получаю из веб-сокета. Функция рендеринга вызывается, когда ее еще нет. Я пытался обновить его с помощью this.state, когда веб-сокет отправил данные, но он не работает. Я использую recharts для отображения BarChart и в данных мне нужно значение из 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"));

Ответы [ 2 ]

1 голос
/ 18 мая 2019

В течение жизненного цикла метода componentDidMount соединение веб-сокета следует открывать только один раз.

Чтобы обновить состояние, необходимо вызвать функцию setState

Вы такженеобходимо закрыть подключение к веб-сокету в методе componentWillUnmount, чтобы избежать утечек памяти

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>
  );
 }
}
0 голосов
/ 18 мая 2019

Вы не можете обновлять, изменяя состояние, вам нужно вызвать функцию:

this.setState(newState)

и укажите объект newState. Смотри https://reactjs.org/docs/react-component.html#setstate

Кроме того, вы не можете установить состояние в функции рендеринга, вам нужно получить данные, например, в componentDidMount, а затем установить состояние там.

...