繁体   English   中英

为什么 socket.io-client 的 socket.on() 会被多次触发?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM