【问题标题】:Converting a class based component to hooks (gapi API)将基于类的组件转换为钩子(gapi API)
【发布时间】:2019-09-21 11:56:42
【问题描述】:

我有这个基于类的组件,它使用呈现按钮的 gapi (Google Auth) API 并且它可以工作:

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()

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

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]);

【问题讨论】:

标签: reactjs react-hooks google-api-js-client


【解决方案1】:

仅 8 个月后,但请尝试使用 useRef 和 auth,如下所示。它对我有用。

   const GoogleAuth  = () => {
      const [isSignedIn, setSignedIn] = useState(null)
      const auth = useRef(null);
      useEffect(() => {
        window.gapi.load('client:auth2', () => {
          window.gapi.client.init({
            clientId:
              'jcu.apps.googleusercontent.com',
            scope: 'email'
          }).then(() => {
            auth.current = window.gapi.auth2.getAuthInstance();
            setSignedIn(auth.current.isSignedIn.get());
            auth.current.isSignedIn.listen(onAuthChange)
          });
        });
      }, [isSignedIn]);
    
     const onAuthChange = () => {
          setSignedIn(auth.current.isSignedIn.get())
      }
    
     if (isSignedIn === null) {
        return (
          <div>I don't know if we are signed in!</div>
        );
      } else if ( isSignedIn ){
        return (
          <div>I am signed in!</div>
        );
      } else {
        return ( <div>I am not signed in. :(</div>);
      }
    }

【讨论】:

    【解决方案2】:

    几个问题 - 您在设置状态后立即引用 auth - auth 在重新呈现新状态之前不会设置。

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

    我想如果用户在设置auth 之前快速点击可能会引发错误,但我发现登录/注销功能能够处理此问题。

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

    My current component state

    【讨论】:

    • 好编辑!我将删除 renderAuthButton() 方法,例如:&lt;button className="ui red google button" onClick={isSignedIn ? onSignOutClick : onSignInClick}&gt; &lt;i className="google icon" /&gt; {!isSignedIn ? 'Sign In' : 'Sign Out'} &lt;/button&gt;
    【解决方案3】:

    只需在 auth.current = ... 之后输入 useEffect setSignedIn(auth.current.isSignedIn.get()); 是事实上的函数onAuthChange 所以这样称呼它:

    .then(() => {
        auth.current = window.gapi.auth2.getAuthInstance();
        onAuthChange();
        auth.current.isSignedIn.listen(onAuthChange);
    });
    

    【讨论】:

      猜你喜欢
      • 2020-09-26
      • 1970-01-01
      • 2019-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-17
      相关资源
      最近更新 更多