【问题标题】:Different WebSocket "onmessage" handlers depending on screen不同的 WebSocket“onmessage”处理程序取决于屏幕
【发布时间】:2021-03-09 01:37:09
【问题描述】:

我的 React Native 应用(iOS 和 Android)使用单个全局 WebSocket 连接。

我想根据屏幕对来自服务器的相同消息做出不同的响应,例如主屏幕 (A) 上的一种方式和屏幕 B 上的不同方式。

因为在屏幕 B 打开后,主屏幕仍处于挂载状态并处于“活动状态”,所以我不能只覆盖 websocket“onmessage”处理程序,因为这会导致不一致。

谁能指出我正在努力实现的正确方向?

【问题讨论】:

    标签: reactjs react-native websocket


    【解决方案1】:

    没有看到关于您想要实现的目标的一些代码,我认为您通常想要的是订阅模型。您只有一个向套接字注册的处理程序,但该处理程序可以委托给可以根据需要添加/删除的其他功能。

    一般来说,我建议在反应树的某处创建 websocket 连接,例如带有上下文提供程序的钩子。不过,为了避免在这里混淆这个想法,我们假设您的 websocket 连接定义为静态上下文(即在模块中,而不是在组件或钩子中)。

    // socket.js
    const messageHandlers = new Set()
    
    export const addMessageHandler = (handler) => {
      messageHandlers.add(handler)
    }
    
    export const removeMessageHandler = (handler) => {
      messageHandlers.delete(handler)
    }
    
    const socket = new WebSocket('ws://example.com')
    
    socket.onmessage = (event) => {
      messageHandlers.forEach((handler) => handler(event))
    }
    

    然后在你的屏幕上:

    import { addMessageHandler, removeMessageHandler } from '/path/to/socket.js'
    
    const SomeScreen = () => {
      useCallback(() => {
        const handler = (event) => { /* do something with event */ }
          
        addMessageHandler(handler)
        return () => removeMessageHandler(handler)
      }, [])
    }
    

    即使屏幕在后台,这也会让监听器保持活跃。如果您使用 react-navigation,您也可以使用useFocusEffect 使其仅在屏幕为当前屏幕时注册,例如:

      useFocusEffect(
        useCallback(() => {
          const handler = (event) => { /* do something with event */ }
          
          addMessageHandler(handler)
          return () => removeMessageHandler(handler)
        }, [])
      )
    

    【讨论】:

    • 我知道您应该避免使用不会进一步添加任何内容的 cmets,但这个解决方案对于我的用例来说绝对完美 - 非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    相关资源
    最近更新 更多