从socket.on.on()内部访问它的内部时空对象
我正在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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论