[英]Why is socket.io-client's socket.on( ) getting fired up multiple times?
因此,由于某些原因,socket.once() 被多次启动,即使它们在 useEffect(); 我 100% 确定我不会在服务器 sde 上多次发出它们。 其中一些事件会多次触发,有时甚至会导致 memory 泄漏。 这是我的 useEffect() function 中的代码;
useEffect(() => {
socket.once('room-joined', (msg) => {
setState({ ...state, roomID: msg.msg, roomJoined: true, room: msg.room, leader: false });
console.log(msg.users);
console.log(msg.msg);
});
socket.once('start-flip', (msg) => {
gotFinalResults = false;
gotResults = false;
normalized = false;
setState({ ...state, game: '/flip' })
});
socket.once('ask-choice-dice', () => {
gotFinalResults = false;
gotResults = false;
normalized = false;
setState({ ...state, game: '/dice' });
});
socket.once('round-result', (msg) => {
rockChoice = 'rock';
setState({ ...state, rockRoundResult: msg, rockChoice: 'rock' });
});
socket.once('race-finished', (msg) => {
console.log(msg);
setState({ ...state, raceFinished: true, raceList: msg });
});
socket.once('message', (msg) => {
console.log(msg);
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
setState({ ...state, chat: [...state.chat, { author: msg.username, msg: msg.msg }] });
});
socket.once('player-disconnected', (msg) => {
setState({ ...state, room: msg.room, chat: [...state.chat, { author: null, msg: msg.msg }] });
});
socket.once('room-created', (msg) => {
console.log(msg.msg);
setState({ ...state, roomID: msg.msg, roomJoined: true, room: msg.room, leader: true });
});
socket.once('new-connection', (msg) => {
setState({ ...state, room: msg.room, chat: [...state.chat, { author: null, msg: msg.msg }] });
});
socket.once('exit-lobby', (msg) => {
setState({ roomID: '', roomJoined: false, joinRoomID: '', chat: [], chatBox: [], room: {}, game: '', leaderQuit: true, leader: false });
});
socket.once('start-race', () => {
gotFinalResults = false;
gotResults = false;
normalized = false;
setState({ ...state, game: '/race' });
});
socket.once('initialize-race', (msg) => {
gotFinalResults = false;
gotResults = false;
normalized = false;
setState({ ...state, game: '/race', raceText: msg.text, raceTimer: true, startTime: performance.now(), raceInitiated: true });
});
socket.once('normalize', () => {
gotResults = false;
gotFinalResults = false;
setState({ ...state, game: '/', choice: Math.floor(Math.random() * 5) + 1, voluntarily: false, timer: { enabled: false }, leaderQuit: false, submitted: false, victory: false, defeat: false, winners: [], loosers: [], rockChoice: 'rock', rockRoundResult: false, rockGameResult: false, raceChoice: '', startTime: null, raceSpeed: 0, raceTimer: false, raceFinished: null, raceList: [], raceInitiated: false, flipChoice: 'heads' });
});
socket.once('defeat', () => {
gotFinalResults = true;
console.log('oh no!')
setState({ ...state, defeat: true });
});
socket.once('results', (msg) => {
setState({ ...state, winners: msg.winners, loosers: msg.loosers });
})
socket.once('victory', () => {
gotFinalResults = true;
setState({ ...state, victory: true });
console.log('oh yes!')
});
});
删除除一个之外的所有.once
调用应该会使问题变得非常明显:
useEffect(() => {
socket.once('room-joined', (msg) => {
setState({ ...state, roomID: msg.msg, roomJoined: true, room: msg.room, leader: false });
console.log(msg.users);
console.log(msg.msg);
});
// lots of other code
});
由于没有依赖数组,因此每次组件重新渲染时都会重新运行此效果回调。 第一次渲染时,将有一个侦听器附加到给定事件。 第二次渲染时,将有两个侦听器附加到给定事件。 等等。
使用一个空的依赖数组来确保.once
只为每种类型调用一次。
您还需要使用 state 设置器的回调形式才能正确更新它。
useEffect(() => {
socket.once('room-joined', (msg) => {
setState(state => ({ ...state, roomID: msg.msg, roomJoined: true, room: msg.room, leader: false }));
console.log(msg.users);
console.log(msg.msg);
});
// lots of other code
}, []);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.