与 Socket.io 反应 - 在“socket.on”事件上不断地重新渲染
Posted
技术标签:
【中文标题】与 Socket.io 反应 - 在“socket.on”事件上不断地重新渲染【英文标题】:React with Socket.io - continously re-render on "socket.on" event 【发布时间】: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)
【问题讨论】:
【参考方案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以上是关于与 Socket.io 反应 - 在“socket.on”事件上不断地重新渲染的主要内容,如果未能解决你的问题,请参考以下文章
在 useEffect 中对 Socket.io 的第一个请求做出反应
Socket.io-client 未连接到 socket.io 服务器反应和节点(快递)