本文介绍了将基于类的组件转换为挂钩(gapi API)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用基于gapi(Google Auth)API的基于类的组件,该API呈现按钮并且可以正常工作:

I have this class based component using the gapi (Google Auth) API that renders a button and it works:

import React from 'react';

class GoogleAuth extends React.Component {
  state = { isSignedIn: null };

  componentDidMount() {
    window.gapi.load('client:auth2', () => {
      window.gapi.client
        .init({
          clientId: process.env.REACT_APP_CLIENT_ID,
          scope: 'email',
        })
        .then(() => {
          this.auth = window.gapi.auth2.getAuthInstance();
          this.handleAuthChange();
          this.auth.isSignedIn.listen(this.handleAuthChange);
        });
    });
  }

  handleAuthChange = () => {
    this.setState({ isSignedIn: this.auth.isSignedIn.get() });
  };

  handleSignIn = () => {
    this.auth.signIn();
  };

  handleSignOut = () => {
    this.auth.signOut();
  };

  renderAuthButton() {
    if (this.state.isSignedIn === null) {
      return null;
    } else if (this.state.isSignedIn) {
      return <button onClick={this.handleSignOut}>Sign Out</button>;
    } else {
      return <button onClick={this.handleSignIn}>Sign in with Google</button>;
    }
  }

  render() {
    return <div>{this.renderAuthButton()}</div>;
  }
}

export default GoogleAuth;

我很难将其转换为使用钩子.主要问题是this.auth ...这就是类如何引用window.gapi.auth2.getAuthInstance()

I'm having a tough time trying to convert this to use hooks. The main issue is this.auth... That's how the class has a reference to window.gapi.auth2.getAuthInstance()

我尝试了许多不同的方法,包括将auth保持在如下状态:

I have tried many different ways including keeping auth in state like:

export default function GoogleAuth() {
    const [isSignedIn, setIsSignedIn] = useState(null);
    const [auth, setAuth] = useState(null);
    useEffect(() => {
        window.gapi.load('client:auth2', () => {
            window.gapi.client
                .init({
                    clientId: process.env.REACT_APP_CLIENT_ID,
                    scope: 'email',
                })
                .then(() => {
                    setAuth(window.gapi.auth2.getAuthInstance());
                    setIsSignedIn(auth.isSignedIn.get());
                    auth.isSignedIn.listen(() => setIsSignedIn(auth.isSignedIn.get()));
                });
        });
    }, [auth]);

推荐答案

问题-设置状态后立即引用auth-在重新渲染auth之前不会对其进行设置它的新状态.

Couple issues - you're referencing auth immediately after you're setting the state - auth won't be set until it re-renders with its new state.

我正在使用类似的代码,因此我不得不在初始设置中使用window.gapi来正确访问返回的身份验证实例.

I'm playing with similar code, and I had to resort to utilizing window.gapi in the initial setup to properly access the returned auth instance.

我想如果在设置auth之前用户快速单击就可以捕获它,那么它可能会引发错误,但是我发现登录/注销功能能够处理此错误.

I imagine it may throw an error if a user clicks quickly they could catch it before auth is set, but I found the sign in/out functions to be able to handle this.

我还发现最容易在隐身模式下进行测试,因为cookie和api的缓存似乎创建了一个不可预测的本地测试环境.

I also found it easiest to test in Incognito, as cookies and cacheing of the api seemed to create an unpredictable local testing environment.

我当前的组件状态

这篇关于将基于类的组件转换为挂钩(gapi API)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 11:11