回调函数未更新状态

Callback function not getting updated state

提问人:Prasadbro 提问时间:3/30/2023 最后编辑:Prasadbro 更新时间:4/1/2023 访问量:234

问:

我不知道为什么我的回调函数没有收到由钩子调用的更新状态,一旦用户更新,我就可以在控制台.log中看到更新的值。disconnectSocket()useWindowUnloadEffect()

当我要重新加载页面时,currentUser有一些值,例如。{name:'john'} 它不是空的。

//App.tsx

function App() {
  const { currentUser } = useContext(UserContext);


  console.log(currentUser); //working

 function disconnectSocket() {
  socket.emit("disconnected", {
      room: "room_1",
      user: currentUser?.name,
      test: "hi",
    });
}

  useWindowUnloadEffect(disconnectSocket);

  useEffect(() => {
    socket.connect();

    socket.on("connect", () => console.log("connected!"));

    socket.on("disconnect", (reason) => {
      if (reason === "io server disconnect") {
        // the disconnection was initiated by the server, you need to reconnect manually
        alert("Player left");
      }
    });
    return () => {
      socket.connected && socket.disconnect();
    };
  }, []);

  return <RouterProvider router={router} />;
}

export default App;
//useWindowUnloadEffect.tsx


import { useEffect } from "react";
type HandlerType = () => void;

const useWindowUnloadEffect = (handler: HandlerType) => {
  useEffect(() => {
    window.addEventListener("beforeunload", handler);

    return () => {
      window.removeEventListener("beforeunload", handler);
    };
  }, []);
};

export default useWindowUnloadEffect;

//UserContext.tsx

import React, { createContext, useState } from "react";

interface User {
  name: string;
}

interface UserContextType {
  currentUser: User | null;
  setCurrentUser: (user: User | null) => void;
}

interface Props {
  children: React.ReactNode;
}

export const UserContext = createContext<UserContextType>({
  currentUser: null,
  setCurrentUser: () => {},
});

export const UserProvider: React.FC<Props> = ({ children }) => {
  const [currentUser, setCurrentUser] = useState<User | null>(null);
  console.log(currentUser);

  return (
    <UserContext.Provider value={{ currentUser, setCurrentUser }}>
      {children}
    </UserContext.Provider>
  );
};

//server.js

const express = require("express");
const app = express();
const cors = require("cors");
const port = process.env.PORT || 4000;
const server = require("http").createServer(app);
const io = require("socket.io")(server, {
  cors: {
    origin: "http://localhost:5173",
  },
});
const room = "room_1";

app.use(cors());
io.on("connection", (socket) => {
  socket.on("join_room", async (data) => {
    const user = {
      username: data.data.username,
      room: room,
      id: socket.id,
    };
    socket.data.user = user;
    // io.sockets.adapter.rooms.forEach((q, r) => {
    //   if (io.sockets.adapter.rooms.get(r).size === 1) {
    //     available_rooms = r;
    //     return;
    //   }
    // });

    socket.join(room);
    if (io.sockets.adapter.rooms.get(room).size === 2) {
      let users = await io.in(room).fetchSockets();
      io.in(room).emit(
        "found-player",
        users.map((s) => s.data)
      );
      io.in(room).emit("start_game", {
        data: { word: "ABCD", defination: "word defination" },
      });
    }
  });
  socket.on("user_guess", ({ user, room, guess }) => {
    io.in(room).emit("user_guess", {
      data: { username: user, guess },
    });
  });
  socket.on("disconnect", (reason) => {
    if (reason && reason === "client namespace disconnect") {
      console.log(reason);
    }
  });
  socket.on("disconnected", (data) => {
    console.log("user disconnected", data);
    io.in(data.room).disconnectSockets(true);
  });
});

server.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});

我已经解决了这个问题,但我还没有找到任何解决方案

reactjs typescript react-hooks socket.io 闭包

评论


答:

0赞 Nikos Paraskevopoulos 3/30/2023 #1

你忘记了依赖关系!调用 in 有一个空的 dependencies 数组。因此,React 认为它不依赖于任何外部值——这是错误的,依赖于 .正因为如此,React 一直使用传递给它第一次被调用的回调,该回调的第一个值为 ,导致你观察到的错误。useEffect(() => { ... }, [])useWindowUnloadEffecthandlercurrentUser.nameuseEffectcurrentUser.name

更改为:useWindowUnloadEffect

import { useEffect } from "react";
type HandlerType = () => void;

const useWindowUnloadEffect = (handler: HandlerType, dependencies: any[]) => {
  useEffect(() => {
    window.addEventListener("beforeunload", handler);

    return () => {
      window.removeEventListener("beforeunload", handler);
    };
  }, dependencies);
};

export default useWindowUnloadEffect;

并将其用作:

useWindowUnloadEffect(disconnectSocket, [currentUser?.name]);

评论

0赞 Prasadbro 3/31/2023
感谢您的快速回复,但仍然不起作用
0赞 Prasadbro 3/31/2023
我添加了localStorage.setItem(“ggdfgdf”, JSON.stringify(currentUser));内部 disconnectSocket 和值更新为最新,但套接字仍然不知何故不知道它
0赞 Nikos Paraskevopoulos 3/31/2023
可能还缺少更多的东西,或者我可能完全错了。您能否分享一个重现错误的在线最小示例以进一步调查?
0赞 Prasadbro 3/31/2023
github.com/PrasadBroo/word_guess_game
0赞 Nikos Paraskevopoulos 4/1/2023
如果没有服务器,这很难测试。不过,在线示例(例如 codesandbox.io)会更好。