将setFoo用作websocket onmessage事件的回调时,无法更新状态

时间:2020-05-15 03:18:18

标签: reactjs websocket closures react-hooks react-state-management

目标:

我正在尝试通过websocket连接从服务器获取消息,并将其添加到名为outgoingMessages的对象数组中。

问题:

调用outgoingMessages时,只有最新消息保存在receive()中。

我怀疑是因为Websocket.onmessage从我调用outgoingMessages开始就只使用connect()的值。我已经尝试了很多,但是还不能解决这个问题。

如何让receive()使用当前状态,而不是初始状态?

谢谢。

const Dashboard = () => {
  const [incomingMessages, setIncomingMessages] = React.useState([]);
  const ws = React.useRef(null);

  const receive = (message) => {
    setIncomingMessages([...incomingMessages, message]);
  };

  const connect = () => {
    ws.current = new WebSocket(WS_URL + "mqtt/ws/messages");
    ws.current.onopen = () => setWsConnected(true);
    ws.current.onclose = () => setWsConnected(false);
    ws.current.onmessage = (event) => receive(event);
  };

  return (<>Stuff</>)
}

1 个答案:

答案 0 :(得分:2)

好像connect函数在初始渲染中被调用过一次,而在receive函数中,incomingMessages的值始终是从closure获得的,因此仅查看最新消息。

要设置状态,请使用功能性设置状态模式,即为setIncomingMessages提供回调。

const Dashboard = () => {
  const [outgoingMessages, setOutgoingMessages] = React.useState([]);
  const ws = React.useRef(null);

  const receive = (message) => {
    setIncomingMessages(prev => [...prev, message]);
  };

  const connect = () => {
    ws.current = new WebSocket(WS_URL + "mqtt/ws/messages");
    ws.current.onopen = () => setWsConnected(true);
    ws.current.onclose = () => setWsConnected(false);
    ws.current.onmessage = (event) => receive(event);
  };

  return (<>Stuff</>)
}

p.s。 -简要说明-您的状态处理outgoingMessages,但您确实为传入消息in设置了接收状态。所以检查一下...