【问题标题】:React with Socket.io - continously re-render on "socket.on" event与 Socket.io 反应 - 在“socket.on”事件上不断地重新渲染
【发布时间】:2018-07-27 21:17:03
【问题描述】:

我正在尝试编写一个客户端,它打开与服务器的 socket.io 连接,然后使用从服务器通过套接字发送的更新数字不断地重新渲染屏幕。我无法获取要更新的号码。 “速度”值保持在 10。有什么问题? - 显然是我理解的一个非常基本的错误。谢谢!

客户端代码:

  import React from 'react';
    import {CircleGauge} from 'react-launch-gauge';
    import io from 'socket.io-client';


    class App extends React.Component {
        constructor(props, context) {
            super(props, context)
            this.state = {
                speed: 10
            };
        }
        componentDidMount() {
            const socket = io.connect('http://localhost:5000');
            socket.on( 'data update', data => this.setState({speed: data}));
            console.log("got the speed: " + this.state.speed);
        }

        render() {
            return (
                <div>
                    <p> The velocity received is: {this.state.speed}  </p>
                </div>
            );
        }
    }
    export default App;

服务器代码:

from flask import Flask, render_template
from flask_socketio import SocketIO, emit
import time

sendData = False;

app = Flask(__name__)
socketio = SocketIO(app)

@socketio.on('connect')
def dataSent():
    print('they connected*************')
    for i in range(20,100):
        emit('data update', i)
        time.sleep(1)
        print(i)


if __name__ == '__main__':
    socketio.run(app, debug = True)

【问题讨论】:

    标签: reactjs flask websocket socket.io react-component


    【解决方案1】:

    在下面检查我的工作代码:

    import React, { useEffect, useState, useRef } from 'react'
    import socket from 'socket.io-client'
    
    const Chatbox = () => {
      const [chats, setChats] = useState([])
      const [message, setMessage] = useState('')
      const socketClientRef = useRef()
    
      useEffect(() => {
        const client = socket("http://localhost:3002");
        client.on("connect", () => {
          console.log('connected')
        })
        client.on("disconnect", () => {
          console.log('diconnected')
        });
        client.on("chat", message => {
          setChats(prevChats => [...prevChats, message])
          // INSTEAD OF:
          // setChats([...chats, message])
        });
        socketClientRef.current = client
        return () => {
          client.removeAllListeners()
        }
      }, [])
    
      const handleSend = async () => {
        socketClientRef.current.emit('chat', {
          room: `event-${eventId}`,
          message
        })
        setMessage('')
      }
    
    
      return (
        <div>
          <div>
            <h1>Messages</h1>
            {chats.map(chat => (
              <div>{chat}</div>
            ))}
          </div>
          <div>
            <input value={message} onChange={e => setMessage(e.target.value)} />
            <button onClick={handleSend}>Send</button>
          </div>
        </div>
      )
    }
    

    【讨论】:

      【解决方案2】:

      您已经接近了,但是您在客户端上设置套接字的方式存在一些小问题。

      首先,您设置的套接字与文档建议的略有不同。

      componentDidMount() {
        // io() not io.connect()
        this.socket = io('http://localhost:5000');
      
        this.socket.on(
          // consider renaming this to 'data_update' or just 'update'
          'data update', 
          data => 
            this.setState(
              { speed: data },
              // the second parameter to setState will be called on completion, so you'll log every time the speed changes
              () => console.log("got the speed: " + this.state.speed)
            )
        );
      
        this.socket.open();
      }
      

      最后,您需要在卸载组件时关闭套接字:

      componentWillUnmount() {
        this.socket.close();
      }
      

      【讨论】:

      • 感谢卢克的回答,但并没有解决问题。由于某种原因,控制台没有显示任何输出(并且速度不会改变),直到服务器发送最终值 99。此时,所有 80 条日志都打印出来,速度更新为 99
      猜你喜欢
      • 2020-03-08
      • 1970-01-01
      • 1970-01-01
      • 2021-04-29
      • 2018-12-27
      • 2018-09-19
      • 2020-12-17
      • 1970-01-01
      • 2022-01-04
      相关资源
      最近更新 更多