Reactjs 将基于类的组件转换为挂钩(gapi API)

Reactjs 将基于类的组件转换为挂钩(gapi API),reactjs,react-hooks,google-api-js-client,Reactjs,React Hooks,Google Api Js Client,我有一个基于类的组件,使用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

我有一个基于类的组件,使用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;

两个问题-在设置状态后立即引用
auth
auth
将不会被设置,直到它以新状态重新呈现

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

我想如果用户快速单击可能会引发错误,他们可以在设置
auth
之前捕获错误,但我发现登录/退出功能能够处理此问题

我还发现,在隐姓埋名的情况下进行测试是最容易的,因为cookies和api的缓存似乎创建了一个不可预测的本地测试环境


才过了8个月,但请使用下面的auth尝试useRef。它对我有用

   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>);
      }
    }
constgoogleauth=()=>{
常量[isSignedIn,setSignedIn]=useState(null)
const auth=useRef(null);
useffect(()=>{
load('client:auth2',()=>{
window.gapi.client.init({
客户ID:
'jcu.apps.googleusercontent.com',
范围:“电子邮件”
}).然后(()=>{
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){
返回(
我不知道我们是否已登录!
);
}否则如果(isSignedIn){
返回(
我已登录!
);
}否则{
返回(我没有登录。:();
}
}

我也遇到了同样的问题。这是帮助我的链接。编辑得很好!我将删除
renderAuthButton()
方法,方法很简单,如:
{!isSignedIn?'Sign-In':'Sign-Out'}
   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>);
      }
    }