【问题标题】:Cannot close the socket when logout注销时无法关闭套接字
【发布时间】:2020-05-20 16:13:03
【问题描述】:
  const [socket, setSocket] = useState(null);
  useLayoutEffect(() => {
    auth().onAuthStateChanged(async (user) => {
      if (!!user) {
        props.login();
        const token = await user.getIdToken(true);
        setSocket(await getSocket(token, props.store));
      } else {
        console.log(socket); // return null when logout
        if (socket) socket.close();
        props.logout();
        setSocket(null);
      }
    });
  }, []);

我正在创建一个使用 socket.io 和 firebase 的 React 应用程序。当用户登录时,我验证并存储套接字,当我注销时,我想断开套接字但我不能。 socket返回null,这是为什么呢?

【问题讨论】:

  • 你确定你的 getSocket() 返回非空值吗?

标签: reactjs firebase socket.io


【解决方案1】:

注销时得到 null 的原因是因为你的 useLayoutEffect 只运行一次,并且 socket 的值是在运行时从闭包中接收的,它是 null

不使用state来存储socket,而是使用ref

const socket = useRef(null);
  useLayoutEffect(() => {
    auth().onAuthStateChanged(async (user) => {
      if (!!user) {
        props.login();
        const token = await user.getIdToken(true);
        socket.current =await getSocket(token, props.store));
      } else {
        console.log(socket.current);
        if (socket.current) socket.current.close();
        props.logout();
        socket.current = null;
      }
    });
  }, []);

【讨论】:

  • 您是否收到任何错误。您还可以验证 getSocket 是否返回正确的套接字值
  • 它工作,现在套接字不为空。之前没用过useRef,请问什么时候用useRef代替useState比较合适,它们有什么区别
  • 状态更新受闭包约束,而 ref 更新适用于突变,当您想要存储不需要触发重新渲染的 const 值以及解决闭包问题时,可以使用 refs。状态是您想要在更改时触发重新渲染时使用的东西
  • 所以我的原始代码问题是回调函数在创建时持有对变量值的引用,因此不响应外部变化。对于 useRef,它创建一个对象,它的值发生变化,因此内存引用可以获得更新的值。我说的对吗?
  • 又出了一个问题,现在我用useRef代替了useState,rerender没有被调用但是我需要它,因为socket是传给其他组件使用的;
【解决方案2】:
const [socket, setSocket] = useState(null);    

  useLayoutEffect(() => {
    let socket;
    auth().onAuthStateChanged(async (user) => {
      if (!!user) {
        const token = await user.getIdToken(true);
        socket = await getSocket(token, props.store)
        setSocket(socket);
        props.login(socket);
      } else {
        if (socket) {socket.close();}
        socket = null;
        setSocket(null);
        props.logout();
        props.clearTodoList();
      }
    });
  }, []);

感谢 Shubham Khatri 的帮助,我想出了一个继续使用 useState 的想法,但要解决关闭问题。

【讨论】:

    猜你喜欢
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    • 2016-04-24
    • 2023-04-09
    相关资源
    最近更新 更多