【问题标题】:React useState not updating, in socket.io events在socket.io事件中反应useState不更新
【发布时间】:2020-09-22 17:06:52
【问题描述】:

我正在尝试在 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 可以得到所需的输出。

【问题讨论】:

  • 能发一下connStatus的结构吗?
  • @Mark 我已经更新了帖子,希望对您有所帮助,connStatus 只是一个具有{ [string] : bool } 结构的对象

标签: reactjs socket.io webrtc


【解决方案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
  };

【讨论】:

  • 我认为你的意思是,setStatus(s => ({ ...connStatus, [user_id]: true })); 因为s.connStatus 为空,但即使是函数签名也不起作用。
  • @sasta_achar,函数的全部意义在于使用previousState,这里记为s并计算下一个状态。所以...s.connState 实际上是正确的。 { ...null, 1: 1 } 也会导致 {1:1}。所以我所拥有的是正确的。祝你好运。
  • 但是如果你只想将你的状态替换为newState,而不使用任何以前的状态你可以使用return newState,为什么要使用额外的{...s.key, newState},我也认为使用prevState (here s) 不需要时可能会在将来造成麻烦,例如如果我的状态类似于state : { connStatus : "some value" },那么您的回答会导致不需要的结果,但是由于在我的情况下它为空,它工作正常
猜你喜欢
  • 2020-10-28
  • 2022-01-17
  • 2023-04-02
  • 2021-01-14
  • 1970-01-01
  • 2020-07-19
  • 1970-01-01
  • 1970-01-01
  • 2020-10-30
相关资源
最近更新 更多