在socket.io事件中反应useState不更新

时间:2020-09-22 17:06:52

标签: reactjs socket.io webrtc

我正在尝试在socket.io事件中更新状态, 但只反映最近的更改,而以前的更改消失了

  const [connStatus, setStatus] = useState({});
  const newConn = (user_id) => {
    console.log("previous ", connStatus);
    console.log("new status ", { ...connStatus, [user_id]: true });
    setStatus({ ...connStatus, [user_id]: true });
  };

我正在使用此功能newConn更新值,

    props.socket.on("ANSWER", (incoming) => {
     
      const desc = new RTCSessionDescription(incoming.sdp);

      peers.current[incoming.caller]
        .setRemoteDescription(desc)
        .then((data) => {
          // set conn as true
          console.log(connStatus, { ...connStatus, [incoming.caller]: true });
          newConn(incoming.caller);
        })
        .catch((e) => console.log(e));
    });

以前的状态始终记录为空{},即其初始值,而新的状态正在更新,但会丢弃所有先前的值。

对于

newConn("key1"); newConn("key2");

日志看起来像这样

previous {}
new status {"key1" : true}

previous {}
new status {"key2" : true}

使用功能签名,例如

  const newConn = (user_id) => {
    setStatus((prevState) => {
      console.log("previous ", prevState);
      console.log("new status ", { ...prevState, [user_id]: true });
      return { ...connStatus, [user_id]: true };
    });
  };

对于

newConn("key1"); newConn("key2"); newConn("key3");

日志看起来像这样

previous {}
new status {"key1" : true}

previous {"key1" : true}
new status {"key1" : true,"key2" : true}

previous {"key2" : true}
new status {"key2" : true,"key3" : true}

更新

我已经找到了解决方案,但不确定为什么可以使用,而我以前的尝试没有解决

  const newConn = (user_id) => {
    setStatus((prevState) => {
      console.log("previous ", prevState);
      console.log("new status ", { ...prevState, [user_id]: true });
      const newState = { ...prevState, [user_id]: true };

      return newState;
    });
  };

使用newConn给了我所需的输出。

1 个答案:

答案 0 :(得分:1)

使用setStatus的功能签名:

const [connStatus, setStatus] = useState({});
const newConn = (user_id) => {
    console.log("previous ", connStatus);
    console.log("new status ", { ...connStatus, [user_id]: true });
    setStatus(s => ({ ...s.connStatus, [user_id]: true }));
           // ^ HERE
  };