【问题标题】:Is there a way to avoid re-render continuously when calling a WebSocket from React component?从 React 组件调用 WebSocket 时,有没有办法避免连续重新渲染?
【发布时间】:2020-09-10 17:51:10
【问题描述】:

当我使用 Websocket 接收数据并将它们更新到 UI 时,我一直在避免组件重新渲染。我有一个名为 A 的组件,我在其中使用 Websocket 来接收实时消息,然后将其显示给 UI。我像这样使用“useEffect”钩子:

function User() {
  let ws = new Websocket(host);
  let [users, setUser] = useState([]);

  useEffect(() => {
   let message = [];
   ws.onmessage = evt => {
     message = JSON.parse(evt.data);
     setUser(message);
   }}, [users]);
 
 return (
    <div className="user-table">
      <Table users={users} />
    </div>
   )
}

由于Websocket频繁有新数据(1秒),导致组件总是更新。那么,有没有什么办法可以避免这个问题呢? (缓存或类似的东西)

【问题讨论】:

  • 你会使用setUser - 你能说明user 是如何使用的吗?它会在某处渲染吗?
  • 我使用 react 钩子声明它。像这样:让 [users, setUser] = useState([])。很抱歉在帖子中遗漏了它。
  • 是的,很明显它是一个钩子,但它在哪里使用?你能展示一下组件是如何渲染的吗?
  • 我真的不明白这里有什么问题。您使用套接字的原因可能是您需要实时数据,如果您想避免频繁获取数据,那么您为什么还要使用 websockets。每当您需要新数据时,只需使用普通的 ajax 请求即可。另外,如果一次渲染对您来说足够了,那么您可以将 `[users]` 更改为 []
  • 嗨,哈利,我正在使用套接字,因为我想确保不会错过任何新数据,并且我希望 UI 在服务器有新数据时自动更新。

标签: reactjs websocket rerender


【解决方案1】:

这里的问题不是套接字本身,而是你的useEffect 依赖数组包含一个状态,useEffect 回调添加了一个监听器,并且回调改变了状态。每次调用 setUser 时,users 都会发生变化 - 当 users 发生变化时,useEffect 会再次运行,因为它的一个依赖项发生了变化。

从依赖数组中删除users,并且只在useEffect 中声明套接字一次,这样你就只有一个套接字(根据User,至少...)一次激活。

function User() {

  const [users, setUsers] = useState([]);

  useEffect(() => {
    const ws = new Websocket(host);
    ws.onmessage = evt => {
      setUsers(JSON.parse(evt.data));
    };
    // Close socket on unmount:
    return () => ws.close();
  }, []); // <-- empty dependency array; only run callback once, on mount
 
  return (
    <div className="user-table">
      <Table users={users} />
    </div>
   );
}

另请注意:

  • 在 ES6 中最好使用 prefer const 而不是 let
  • 为减少错误,请适当命名变量 - 如果您有多个用户,请使用 userssetUsers。 (如果您只有一个用户,请使用 usersetUser

如果有可能存在多个User,最好只在父级中创建一次套接字,然后将其作为道具传递下去;这样,您就不会创建多个执行相同操作的套接字。

【讨论】:

  • 感谢您的帮助。我意识到我的问题是套接字总是发送一次大约 1 秒的数据。
猜你喜欢
  • 2020-07-31
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 2016-08-01
  • 2019-04-27
  • 2020-12-13
相关资源
最近更新 更多