如何解决为什么我的socket.io事件侦听器可以在UI组件上正常工作,但在React的其他组件上却无法工作?
我有一个奇怪的错误正在尝试解决(或者因为我是React的新手,所以让它变得很奇怪)。我正在使用React和TypeScript构建一个应用程序,该应用程序将允许我订阅某些主题,以便接收值并实时在UI中显示我。
简而言之,我有一个包含主题的数组,并且正在遍历该数组以动态创建UI元素:
{selectedTopics.map((topic: any,idx: number) =>
< Slider key={idx}
topic={topic}
socket={socket} // socket.on is working on this component
selectedTopics={selectedTopics}
setSelectedTopics={(topics: any) => setSelectedTopics(topics)}
/>)
}
<CustomComponent socket={socket} /> // socket.on is not working on this component
如您所见,我正在根应用程序中创建一个全局套接字连接,并将其作为prop传递给子级。然后,我在子组件中调用props.socket.on('subscribe',callback);
。
这是我的子组件(滑块)代码:
const Slider: React.FC<{
socket: SocketIOClient.socket;
topic: any;
selectedTopics: any;
setSelectedTopics: any;
}> = (props) => {
const [realTimeValue,setRealTimeValue] = useState<string>("");
const [loading,setLoading] = useState<boolean>(false);
const [subscribed,setSubscribed] = useState<boolean>(false);
const onSubscribe = (topic: any) => {
props.socket.on("onSubscribe",(data: any) => {
const name = data.Name;
const payload = data.Value;
console.log(`received response with name: ${name} and payload: ${payload}`);
if (topic.name === name) {
console.log(`topic received= ${name} correspond to tpic name = ${topic.name}`);
setSubscribed(true);
setRealTimeValue(payload);
setLoading(false);
}
else {
console.log(`received topic = ${name} but current was ${topic.name} `);
}
});
}
const subscribe = (topic: any) => {
/* I'm invoking this function with a click button. So when the user clicks,then this function will be triggered.
*/
const req = {
subscribe: topic.Topic,}
props.socket.emit('subscribe',req);
setLoading(true);
onSubscribe(topic);
}
.
.
.
您可以看到,我这样做是因为我需要将事件发送到指定主题名称的服务器,以便对服务器说,嘿,我想订阅这个特定主题。我不知道这是否是最好的方法,因为我为所有UI组件调用了相同的事件和回调函数。
这非常有效,这不是我的问题。我的问题是我还将这个全局套接字对象也传递给了下一个UI组件CustomComponent
。这是我的代码的简化版本:
import React,{ useState,useEffect } from 'react';
import { IonLabel} from '@ionic/react';
const Custom: React.FC<{
socket: SocketIOClient.socket;
}> = (props) => {
const [temp,setTemp] = useState("");
const handle = (data: any) => {
console.log(`**received ${data}`);
setTemp("received");
}
useEffect(() => {
console.log("useEffect called ..")
console.log(`height: ${window.innerHeight} | width: ${window.innerWidth}`);
props.socket.on('onCustom',handle);
},[]) // I tried passing temp,setTemp and props.socket in the dependencies array but nothing worked. However,this works when I pass the handle function in the dep array or not pass any array at all. But not quite as expected because it renders many times until my app freezes.
return (
<IonLabel>{temp}</IonLabel>
);
};
export default Custom;
如您所见,我正在使用useEffect
钩子在组件安装时调用socket.on
,因为我希望它在组件安装时运行,而不是像滑块组件。
现在这不起作用,我无法使用从服务器发送的消息。就像我的props.socket.on
无法正常工作,这意味着它没有在侦听来自服务器的传入响应。令人惊讶的是,当我完全不传递数组依赖项或在依赖项数组中传递handle函数时,此方法起作用。但是,这每秒渲染一千次,一段时间后,该应用程序冻结了,我什么也没做。
编辑
我正在应用程序组件外部创建套接字实例,这样它就不会一直呈现。我不知道这是否是合适的方法。所以我有这样的东西:
const socket = socketIOClient(serverHost);
const App: React.FC = () => {
.
.
.
.
如您所见,我正在外部创建套接字,并通过将其传递给子组件在应用程序组件中使用它们。
解决方法
我不确定这是否行得通。尝试将handle
函数移到useEffect
回调中,并在temp
中添加useEffect(() => {
console.log("useEffect called ..")
console.log(`height: ${window.innerHeight} | width: ${window.innerWidth}`);
props.socket.on('onCustom',(data: any) => {
console.log(`**received ${data}`);
setTemp("received");
});
},[temp])
:
SELECT time('now','+5 hours') as nowTime,time(restaurants.open_from) as openTime,time(restaurants.close_at) as closeTime,CASE
WHEN time(restaurants.open_from) > time(restaurants.close_at) THEN time('now','+5 hours') >= time(restaurants.open_from) or time('now','+5 hours') < time(restaurants.close_at)
when time(restaurants.open_from) < time(restaurants.close_at) THEN time('now','+5 hours') >= time(restaurants.open_from) and time('now','+5 hours') < time(restaurants.close_at)
END is_opened
from restaurants
WHERE is_opened >0
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。