从socket.on.on()内部访问它的内部时空对象

发布于 2025-01-27 08:05:51 字数 3854 浏览 2 评论 0原文

我正在Web浏览器中开发多人游戏,并且使用React和Socket.io。 在下面的代码中,我有一个React组件,该组件可以处理和显示播放器列表及其得分。

  • 当玩家输入正确的答案时,在服务器端填充了插座事件,并被socket.on捕获(“ rightanswer”,...)

  • 每秒钟,插座事件在服务器端被捕获并被捕获。 socket.on(“ updatesCore”,...)。在回调函数中,我尝试访问Scorelist对象(这是我的React组件的道具,它是父组件中的usestate())。然后,我有一个可变的温度,这是1个玩家的增量分数,最后,我更新了我的Scorelist

Iswinnerlist,应该看起来像: {player1:false, 玩家2:false, ... } Scorelist是相似的,但它代替了布尔来存储整数。

我不明白的是我的对象iswinnerlist和Scorelist在我做游戏机时看起来很空,并且没有更新我的分数。

我会错过范围的东西吗?我希望我的道具和状态在我的反应组件内的任何地方都可以使用。

在亚历山大的答案之后,请提前您的答案

import React, { useContext, useEffect, useState } from 'react';
import { useCallback } from 'react';
import { SocketContext } from '../../context/socket';
import PlayerBoard from './PlayerBoard/PlayerBoard';

import './Scoreboard.css';

const Scoreboard = ({users, scoreList, setScoreList}) => {
  const socket = useContext(SocketContext);

  const [isWinnerList, setIsWinnerList] = useState({});

  useEffect(() => {
    socket.on('rightAnswer', ({ user }) => {
      console.log(isWinnerList);
      console.log(isWinnerList[user]);

      let temp = {};
      temp[user] = true;
      setIsWinnerList(isWinnerList => ({...isWinnerList,...temp}));
    });
    
    socket.on('updateScore', ({users}) => {
      console.log(scoreList);//this displays an empty Object
      console.log(isWinnerList);//this displays an empty Object
      for(const user of users){
        let temp = {};
        if(isWinnerList[user.name] === false){
          console.log("updating score");
          temp[user.name] = scoreList[user.name] + 3;
          setScoreList(scoreList => ({...scoreList,...temp}));
        } else {
          // console.log("user " + user.name + " has won");
        }
      }
    });
  },[]);

  useEffect(() => {
    for(let i = 0; i < users.length; i++){
      let temp = {};
      if(!(users[i].name in isWinnerList)){
        // console.log("adding " + users[i].name);
        temp[users[i].name] = false;
        setIsWinnerList( isWinnerList => ({...isWinnerList, ...temp}));
      }
    }
  }, [users]);

  return (
    <div className='outerScoreboard'>
      {users
        ? (
          <div className='innerScoreboard'>
            {users.map(({ name }) => (
              <div key={name} className='scoreboardItem'>
                <PlayerBoard name={name} isWinner={isWinnerList[name]} score={scoreList[name]} />
              </div>
            ))}
          </div>
        )
        : <div> no users </div>
      }
    </div>
  )
};
export default Scoreboard;

,它尝试了以下方法:

useEffect(() => {
    socket.on('rightAnswer', ({ user }) => {
      console.log(isWinnerList);
      console.log(user);
      console.log(isWinnerList[user]);

      let temp = {};
      temp[user] = true;
      setIsWinnerList(isWinnerList => ({ ...isWinnerList, ...temp }));
    });
  }, [socket]);

  useEffect(() => {
    // socket.on('updateScore', test);
    console.log("useEffect executed");

    socket.on('updateScore', ({ users }) => {
      console.log(scoreList);
      console.log(isWinnerList);

      for (const user of users) {
        let temp = {};
        if (isWinnerList[user.name] === false) {
          console.log("updating score");
          temp[user.name] = scoreList[user.name] + 3;
          setScoreList(scoreList => ({ ...scoreList, ...temp }));
        } else {
          // console.log("user " + user.name + " has won");
        }
      }
    });
  }, [isWinnerList]);

但是socket.on中的代码('updatesCore',...)现在被执行两次。 (虽然Console.log(“执行使用效率”)仅执行一次。如何?)

终端还会给我警告,并告诉我将Scorelist,SetScorelist和Socket添加到依赖项列表中。我希望那里有无限的循环。当我使用完整依赖项列表运行代码时,socket.on(“ updatesCore”,...)每次执行更多次。导致“准”无限循环

I am developing a multiplayer game in a web browser and I use react and socket.io.
In the code below, I have a react component which handles and displays the player list and their score.

  • When the player entered the right answer, a socket event is emmited at server side and is caught by socket.on("rightAnswer",...)

  • Every seconds, a socket event is emmited at server side and is caught by socket.on("updateScore",...). In the callback function, I try to access the scoreList object (which is a prop of my react component and it is a useState() in a parent component). Then, I have a variable temp which is the incremented score for 1 player and finally, I update my scoreList

isWinnerList should look like:
{player1: False,
player2: False,
...
}
and scoreList is similar but instead of boolean, it stores integers.

What I don't understand is my objects isWinnerList and scoreList look empty when I do a console.log and my scores are not updated.

Do I miss something with the scope ? I would expect my props and States to be available anywhere inside my react component.

Thanks in advance for your answers

import React, { useContext, useEffect, useState } from 'react';
import { useCallback } from 'react';
import { SocketContext } from '../../context/socket';
import PlayerBoard from './PlayerBoard/PlayerBoard';

import './Scoreboard.css';

const Scoreboard = ({users, scoreList, setScoreList}) => {
  const socket = useContext(SocketContext);

  const [isWinnerList, setIsWinnerList] = useState({});

  useEffect(() => {
    socket.on('rightAnswer', ({ user }) => {
      console.log(isWinnerList);
      console.log(isWinnerList[user]);

      let temp = {};
      temp[user] = true;
      setIsWinnerList(isWinnerList => ({...isWinnerList,...temp}));
    });
    
    socket.on('updateScore', ({users}) => {
      console.log(scoreList);//this displays an empty Object
      console.log(isWinnerList);//this displays an empty Object
      for(const user of users){
        let temp = {};
        if(isWinnerList[user.name] === false){
          console.log("updating score");
          temp[user.name] = scoreList[user.name] + 3;
          setScoreList(scoreList => ({...scoreList,...temp}));
        } else {
          // console.log("user " + user.name + " has won");
        }
      }
    });
  },[]);

  useEffect(() => {
    for(let i = 0; i < users.length; i++){
      let temp = {};
      if(!(users[i].name in isWinnerList)){
        // console.log("adding " + users[i].name);
        temp[users[i].name] = false;
        setIsWinnerList( isWinnerList => ({...isWinnerList, ...temp}));
      }
    }
  }, [users]);

  return (
    <div className='outerScoreboard'>
      {users
        ? (
          <div className='innerScoreboard'>
            {users.map(({ name }) => (
              <div key={name} className='scoreboardItem'>
                <PlayerBoard name={name} isWinner={isWinnerList[name]} score={scoreList[name]} />
              </div>
            ))}
          </div>
        )
        : <div> no users </div>
      }
    </div>
  )
};
export default Scoreboard;

after Alexander's answer, it tried this:

useEffect(() => {
    socket.on('rightAnswer', ({ user }) => {
      console.log(isWinnerList);
      console.log(user);
      console.log(isWinnerList[user]);

      let temp = {};
      temp[user] = true;
      setIsWinnerList(isWinnerList => ({ ...isWinnerList, ...temp }));
    });
  }, [socket]);

  useEffect(() => {
    // socket.on('updateScore', test);
    console.log("useEffect executed");

    socket.on('updateScore', ({ users }) => {
      console.log(scoreList);
      console.log(isWinnerList);

      for (const user of users) {
        let temp = {};
        if (isWinnerList[user.name] === false) {
          console.log("updating score");
          temp[user.name] = scoreList[user.name] + 3;
          setScoreList(scoreList => ({ ...scoreList, ...temp }));
        } else {
          // console.log("user " + user.name + " has won");
        }
      }
    });
  }, [isWinnerList]);

but code inside of socket.on('updateScore',...) is executed twice now. (while the console.log("useEffect executed") is executed only once. How ? )

Terminal also gives me warning and tell me to add scoreList, setScoreList and socket to the dependency list. I would expect an infinite loop there. When I run the code with the full dependency list, socket.on("updateScore",...) is each time executed more times. Resulting in a "quasi" infinite loop

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文