обновления от сокета сервера не воспроизводятся в реагирующем интерфейсе - PullRequest
0 голосов
/ 18 июня 2019

Я отправляю тупые данные с сервера узла каждые x мс.

Я хочу, чтобы эти данные появлялись в реальном времени.

Проблема в том, что после инициализации компонент Tile не меняется

Я также создал кликабельную плитку, поэтому при ее нажатии появляется модальное окно, в котором обновляются данные.

Я читал, что всякий раз, когда вы устанавливаете состояние, повторные вызовы отображаются, но это не влияет на компонент тайла. обновленная информация

* +1012 *not updated in real time

сервер узла:


const express = require("express");
const http = require("http");
const socketIo = require("socket.io");

const app = express();
const server = http.createServer(app).listen(5001);
const io = socketIo(server);

io.set('origins', 'http://localhost:3000');
let today = new Date();
let time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
let data ={
  "news" :
      { "short" :'Hello short news '  + time,
    "long" : 'Hello long news '  + time
  },
  "weather" : {
    "short" : 'really hot today '  + time,
    "long" : 'drink a lot '  + time
  }
};

io.on('connection', function(socket){
  console.log('connected');
  socket.emit('initial_data',data);
  socket.on('data',() => {
    socket.emit('get_data', data);
  });

  setInterval(function() {
    today = new Date();
    time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
    let newsUpdate ={
      "news" :
          { "short" :'Hello short news '  + time,
            "long" : 'Hello long news '  + time
          }
    };
    socket.emit('news_update', newsUpdate);
    console.log('Last updated: ' + today);
  }, 400); //600000 is 10 min

  setInterval(function() {
    today = new Date();
    time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
    let newsUpdate =   {"weather" : {
      "short" : 'really hot today '  + time,
          "long" : 'drink a lot '  + time
    }};
    socket.emit('weather_update', newsUpdate);
    console.log('Last updated: ' + time);
  }, 400); //600000 is 10 min

});


module.exports = app;

React UI: Приборная панель

import React from 'react';
import {Modal} from 'react-bootstrap'

import {ButtonBase,Grid,Card,CardContent} from '@material-ui/core';
import socketIOClient from 'socket.io-client';

import {Tile} from './Tile';


export class DashBoard extends React.Component{

    showModal = (card) => {
        this.setState({ [card]: true});
    };

    hideModal = (card) => {
        this.setState({ [card]: false });
    };

    constructor(props) {
        super(props);
        this.showModal = this.showModal.bind(this);
        this.hideModal = this.hideModal.bind(this);
        this.state = {
            showWeather: false,
            showNews:false,
            response:false,
            news_response: false,
            weather_response:false,
            endpoint: "http://localhost:5001"
        };
    }

    componentDidMount() {
        const {endpoint} = this.state;
        const socket = socketIOClient(endpoint);
        socket.on('initial_data', (data) => {
            this.setState({news_response: data["news"] ,weather_response :data["weather"] });
            console.log(this.state);
        });
        socket.on("news_update", data => {this.setState({news_response: data["news"]});});
        socket.on("weather_update", data => {this.setState({weather_response: data["weather"]});});
        this.forceUpdate();
    }

    render(){
        if(this.state.weather_response && this.state.news_response)
        return(
            <>
                <Grid
                    container
                    direction="column"
                    justify="center"
                    alignItems="center">
                <Card>
                    <CardContent>
                        <ButtonBase onClick={() => this.showModal('showNews')}>
                            <Tile title={"Lets get some news here!"} short={this.state.news_response["short"]}></Tile>
                        </ButtonBase>
                    </CardContent>
                </Card>
                <Card>
                    <CardContent>
                        <ButtonBase onClick={() => this.showModal('showWeather')}>
                            <Tile title={"Lets get weather conditions here!"} short={this.state.weather_response["short"]}> </Tile>
                        </ButtonBase>
                    </CardContent>
                </Card>
                </Grid>
                <Modal show={this.state.showNews} onHide={()=>this.hideModal('showNews')}>
                    <Modal.Header closeButton> </Modal.Header>
                    <Modal.Body> <Tile title={"Lets get some news here!"} short={this.state.news_response["short"]} long={this.state.news_response["long"]}> </Tile> </Modal.Body>
                </Modal>
                <Modal show={this.state.showWeather} onHide={()=>this.hideModal('showWeather')}>
                    <Modal.Header closeButton></Modal.Header>
                    <Modal.Body> <Tile title={"Lets get weather conditions here!"} short={this.state.weather_response["short"]} long={this.state.weather_response["long"]}> </Tile></Modal.Body>
                </Modal>
            </>
        );
        else
            return(<>Loading...</>)
    }
}

Компонент плитки:

import React from 'react';

export class Tile extends React.Component{

    constructor(props){
        super(props);
        this.state={title:this.props.title,
            short: this.props.short ,
            long:this.props.long};
    }

    render(){
        return(
            <div>
            <h1>{this.state.title}</h1>
                <p>{this.state.short}</p> <br></br>
                {this.state.long}
            </div>
        );
    }
}

1 Ответ

0 голосов
/ 19 июня 2019

согласно этому посту https://medium.com/@hugoleon46/for-anyone-that-needs-this-functionality-a-little-update-7b7bdbe8cc1f

решается добавлением компонента Tile:

    static getDerivedStateFromProps(props, state) {
        if (props.short !== state.short || props.long !== state.long ) {
            return { short: props.short , long: props.long };
        }
        return null;
    }
...