当前位置: 首页 > 知识库问答 >
问题:

前端 - 全局的原生webSocket写在什么位置?

南宫浩皛
2023-11-02

1.umi项目中的model是全局的,如果我写在model里:socket.ts,取得的数据用useState保存,那所有用到这个model的组件都会随着useState的更新而更新,不管有没有用到变化的数据。
2.如果我把socket写在ts文件中,import它,要怎么在其它组件中拿到数据。

上面的两点都可以通过事件总线,在收到数据时emit出来,但是看起来这个操作有点多余。

共有2个答案

欧阳何平
2023-11-02

用自定义Hook:

// useWebSocket.jsimport { useState, useEffect } from 'react';function useWebSocket(url) {  const [data, setData] = useState(null);  const [socket, setSocket] = useState(null);  useEffect(() => {    const ws = new WebSocket(url);    setSocket(ws);    ws.onmessage = (event) => {      setData(JSON.parse(event.data));    };    return () => {      ws.close();    };  }, [url]);  return { data, socket };}export default useWebSocket;

在你的组件里用Hook:

import useWebSocket from './useWebSocket';function MyComponent() {  const { data, socket } = useWebSocket('ws://example.com/socket');  // ...}

或者用Context API:

// WebSocketContext.jsimport React, { useState, useEffect, createContext } from 'react';export const WebSocketContext = createContext();export function WebSocketProvider({ children }) {  const [data, setData] = useState(null);  const [socket, setSocket] = useState(null);  useEffect(() => {    const ws = new WebSocket('ws://example.com/socket');    setSocket(ws);    ws.onmessage = (event) => {      setData(JSON.parse(event.data));    };    return () => {      ws.close();    };  }, []);  return (    <WebSocketContext.Provider value={{ data, socket }}>      {children}    </WebSocketContext.Provider>  );}

然后在你的组件里:

import React, { useContext } from 'react';import { WebSocketContext } from './WebSocketContext';function MyComponent() {  const { data, socket } = useContext(WebSocketContext);  // ...}
云和惬
2023-11-02

确实,这个问题涉及到了在React/UMI项目中如何全局使用WebSocket,以及如何在组件之间共享数据的问题。

首先,对于你的第一个问题,把WebSocket写在model里并使用useState保存数据,确实会导致所有使用这个model的组件都会随着useState的更新而更新,不管有没有用到变化的数据。这是由于React的响应性系统导致的,当state更新时,所有的依赖这个state的组件都会重新渲染。

然后,对于你的第二个问题,如果你把WebSocket写在单独的ts文件中,并导入到其他组件中,那么你需要通过事件或者状态管理来在组件之间共享数据。你已经提到了使用事件总线来在收到数据时emit出来,这是一种可行的方案。但是这确实看起来有些多余,如果你已经在组件之间共享了WebSocket实例,那么每个组件都需要单独处理接收到的数据,这可能会产生很多重复的代码。

一个更好的解决方案可能是使用一个专门的状态管理库,比如Redux或者Mobx。你可以在应用程序的根组件中使用WebSocket,并把接收到的数据存储在状态管理库中。然后你可以在任何需要这些数据的组件中使用状态管理库的API来获取数据。这样只有真正需要数据的组件才会因为数据的变化而更新。

如果你不想使用状态管理库,还有一个可行的方案是使用React的Context API。你可以创建一个包含WebSocket实例和接收到的数据的Context,然后让需要这些数据的组件都使用这个Context。当数据变化时,只有依赖这个Context的组件才会更新。

总的来说,这个问题没有简单的答案,因为解决方案取决于你的应用程序的具体需求和结构。你可能需要结合使用上述的几种方法来解决你的问题。

 类似资料:
  • 我们知道命名空间: 但是什么是全局命名空间呢?

  • 宽度不定,间距相同,左对齐。

  • 设置超时时间是50毫秒,接口还能正常请求,超时时间不生效 全局设置axios.defaults.timeout = 50 也不生效

  • 问题内容: 什么是 全球声明 ?以及如何使用?我已经阅读了Python的官方定义; 但是,这对我来说没有多大意义。 问题答案: python中的每个“变量”都限于特定范围。python“文件”的范围是模块范围。考虑以下: 具有局部作用域的对象会在函数退出后立即死亡,并且永远无法检索(除非您拥有它们),但是在函数内,您可以访问模块级作用域(或任何包含的作用域)中的变量: 但是,您不能在该引用上使用赋

  • Ant Design做全局汉化的时候,为什么日期组件需要额外导入这个汉化包,如果不导入的话,月份和日期就还是默认的英文的,在源码里是怎么写的,不太明白。请大佬指点 另外还有一个问题想请教,为什么这个ConfigProvider直接包裹在App外面不可以,要包在RouterProvider或者Provider里才生效。

  • 主要内容:什么是云原生,云原生的4大组件,如何云原生什么是云原生 技术的变革,一定是思想先行,云原生是一种构建和运行应用程序的方法,是一套技术体系和方法论。云原生(CloudNative)是一个组合词,Cloud+Native。Cloud表示应用程序位于云中,而不是传统的数据中心;Native表示应用程序从设计之初即考虑到云的环境,原生为云而设计,在云上以最佳姿势运行,充分利用和发挥云平台的弹性+分布式优势。Pivotal公司的Matt Stine