状态未立即用socket.io保存

问题描述 投票:0回答:1

正如您在下面的问题中看到的,我收到一条消息,其中包含操作停止。我在那里更新了 3 个状态变量。我的问题是

setTotalScore
totalScore
一开始是0,当我收到消息时,我将其更新为与
user.score
相同。但是,如果我再次收到该消息,它又会变成 0,尽管它不应该是这样。我到处都读到,这是
useState
更新方式的问题。我真的不知道如何解决这个问题。这是代码:

socket.on(`${WsTopic.GAME}/${WsAction.STOP}`, (payload) => {
  const user = payload.find((entry: any) => entry.username == name)
  if (user) {
    console.log("USER: ", user," USER.SCORE: ", user.score);
    console.log("SCORE: ", totalScore);

    const addedScore = user.score - totalScore;

    setTotalScore(user.score);
    setAddedScore(addedScore);
    setShowAnswer(true);
  }
})
const [totalScore, setTotalScore] = useState<number>(0);

totalScore
应始终更新并等于
user.score
。你可以把它看成
totalScore
user.score
的上一个分数。

node.js typescript sockets react-hooks socket.io
1个回答
0
投票

这是一个 Javascript 关闭问题,套接字会在渲染周期中的

totalScore
状态值上关闭,其中套接字事件处理程序被实例化并移交给套接字。

您可以使用具有适当依赖关系的

useEffect
来重新封装变量:

React.useEffect(() => {
  const stopHandler = (payload) => {
    const user = payload.find((entry: any) => entry.username == name);
    if (user) {
      console.log("USER: ", user," USER.SCORE: ", user.score);
      console.log("SCORE: ", totalScore);

      const addedScore = user.score - totalScore;

      setTotalScore(user.score);
      setAddedScore(addedScore);
      setShowAnswer(true);
    }
  };

  socket.on(`${WsTopic.GAME}/${WsAction.STOP}`, stopHandler);

  return () => {
    socket.off(`${WsTopic.GAME}/${WsAction.STOP}`, stopHandler);
  };
}, [totalScore]); 

您还可以使用 React ref 来缓存当前

totalScore
状态值并在处理程序中引用它:

const [totalScore, setTotalScore] = useState<number>(0);
const totalScoreRef = React.useRef(totalScore);

React.useEffect(() => {
  totalScoreRef.current = totalScore;
}, [totalScore]);

React.useEffect(() => {
  const stopHandler = (payload) => {
    const user = payload.find((entry: any) => entry.username == name);
    if (user) {
      console.log("USER: ", user," USER.SCORE: ", user.score);
      console.log("SCORE: ", totalScoreRef.current);

      const addedScore = user.score - totalScoreRef.current;

      setTotalScore(user.score);
      setAddedScore(addedScore);
      setShowAnswer(true);
    }
  };

  socket.on(`${WsTopic.GAME}/${WsAction.STOP}`, stopHandler);

  return () => {
    socket.off(`${WsTopic.GAME}/${WsAction.STOP}`, stopHandler);
  };
}, []); 
© www.soinside.com 2019 - 2024. All rights reserved.