为什么我的socket.io事件侦听器可以在UI组件上正常工作,但在React的其他组件上却无法工作?

如何解决为什么我的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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?