为什么 useState() 会重复 websocket 事件?

IT技术 reactjs websocket react-hooks
2021-05-20 22:58:27

我的react组件正在通过 websocket 从服务器接收消息。当我尝试使用 useState() 更新状态时,套接字会重复。

如果我这样做...

import React, {useState} from 'react'

export default () => {

    let[message, setMessage] = useState()

    let ws = new WebSocket("ws://blah");

    ws.onmessage = (e) => {
        let obj = JSON.parse(e.data);

        // event name
        console.log(obj.event);

        // event data
        console.log(obj.value);

        // setMessage(obj.value)

        ws.close
    }
    return <div>
            {message}

    </div>
}

然后控制台按预期单独显示每条消息

但是如果我回评论,setMessage(object.value)那么每条消息的所有连接都会重复

setMessage() 以某种方式导致连接累积

2个回答

那是因为您要在每次渲染时创建一个新的 websocket。

由于连接到网络套接字是一种“副作用”,您将需要使用 useEffect

import React, {useState} from 'react'

export default () => {

  let [message, setMessage] = useState()

  React.useEffect(() => {
    let ws = new WebSocket("ws://blah");

    ws.onmessage = (e) => {
      let obj = JSON.parse(e.data);

      // event name
      console.log(obj.event);

      // event data
      console.log(obj.value);

      setMessage(obj.value);
    };

    return () => {
      ws.close()
    }
  }, [])


  return (
    <div>
      {message}
    </div>
  );
}

或者,您可以将 websocket 声明移出函数这样,您可以在以下任何地方使用它useEffect

import React, {useState} from 'react'
import { w3cwebsocket as W3CWebSocket } from 'websocket';

const ws = new W3CWebSocket("ws://blah");

export default () => {

  let [message, setMessage] = useState()

  React.useEffect(() => {
    ws.onmessage = (e) => {
      //...
      setMessage(obj.value);
    };

    return () => {
      ws.close()
    };
  }, []);


  return (
    <div>
      {message}
    </div>
  );
};