如何删除 Google OAuth2gapi 事件侦听器?

Lev*_*yan 3 javascript oauth-2.0 google-api-js-client reactjs google-signin

我真的很难理解如何删除谷歌gapi事件监听器。下面粗体是所讨论的完整功能。

window.gapi.auth2.getAuthInstance().isSignedIn.listen(onAuthChange);
Run Code Online (Sandbox Code Playgroud)

我想在 useEffect 挂钩中使用清理函数来删除事件侦听器,但执行此操作的实际代码...我认为与简单的 javascript“removeEventListener”不同?我在谷歌文档中找不到任何内容。我的问题是我需要知道其他页面上的身份验证状态何时发生变化,并且需要其他函数在事件触发时运行(身份验证状态更改) - 但由于原始版本不断运行,我最终得到了一堆不必要的函数调用。当您登录和退出时,情况会变得更糟......随着事件侦听器的累积。


import React, { useEffect, useContext, useState } from "react";
import history from "../history";
import { GeneralContext } from "../contexts/General";

const GoogleAuth = () => {
  const { state, setState } = useContext(GeneralContext);

  const onAuthChange = () => {
    const auth = window.gapi.auth2.getAuthInstance();
    setState({ authStatus: auth.isSignedIn.get() });

    if (auth.isSignedIn.get() === true) {
      const token = auth.currentUser.fe.qc.access_token;
      setState({ accessToken: token });
    }
  };

  // Check auth status on mount
  useEffect(() => {
    window.gapi.load("client:auth2", () => {
      window.gapi.client
        .init({
          clientId:
            "320808104510-qjdjiooodidc8jm1i000oteqc7h63029.apps.googleusercontent.com",
          scope: "https://www.googleapis.com/auth/books",
        })
        .then(() => {
          const auth = window.gapi.auth2.getAuthInstance();
          //setState({ authStatus: auth.isSignedIn.get() });
          console.log("Event listender mounted on Sign-in Page");
          auth.isSignedIn.listen(onAuthChange);
        });
    });
  }, []);

  const onClick = () => {
    console.log(state.authStatus);
    const auth = window.gapi.auth2.getAuthInstance();
    auth.signIn();
    //setState({ authStatus: auth.isSignedIn.get() });
  };

  // Proceed to next page if user Signs into Google
  const proceed = () => {
    //Verify sign in
    if (state.authStatus === true) {
      //console.log("I am signed in");
      history.push("/home");
    }
  };

  // Runs after state updates
  useEffect(() => {
    proceed();

    return () => {
      // console.log("GoogleAuth Unmounted");
      // const auth = window.gapi.auth2.getAuthInstance();
      // window.removeEventListener(onAuthChange(), auth.isSignedIn.listen()); <--This is my attempt to remove the event listender, but it didn't work! 
    };
  }, [state.authStatus]);

  return (
    <React.Fragment>
      <div to="/" className="login btn" onClick={onClick}>
        Sign in with Google
        <svg className="google__svg">
          <use xlinkHref="img/sprite.svg#icon-google"></use>
        </svg>
      </div>
    </React.Fragment>
  );
};

export default GoogleAuth;

Run Code Online (Sandbox Code Playgroud)

Par*_*ich 5

我遇到了同样的问题,并且找不到任何文档来指导我正确的方向。虽然我找到的文档和打字稿打字都表明auth.isSignedIn.listen()没有返回值,但在浏览器控制台中检查返回值表明情况并非如此。

它返回一个对象,并且该对象remove()在其原型上有一个方法。添加侦听器时保存返回的对象,并remove在清理中调用其方法。

  useEffect(
      () => {
        let listenerContext;

        window.gapi.load('client:auth2', () => {
          window.gapi.client.init({
            clientId,
            discoveryDocs: [...DISCOVERY_DOCS],
            scope: SCOPES,
          }).then(() => {
            const auth = window.gapi.auth2.getAuthInstance();
            listenerContext = auth.isSignedIn.listen(onSigninChange);
            // ... etc
          });
        });

        return () => {
          listenerContext?.remove();
        };
      },
      [],
  );
Run Code Online (Sandbox Code Playgroud)

因为我找不到任何文档,所以我不能声称这是一个稳定的长期功能。至少,我希望它能帮助你在你的项目中畅通无阻。