代码之家  ›  专栏  ›  技术社区  ›  Dariusz Legizynski

将基于类的组件重构为钩子(gap API)

  •  0
  • Dariusz Legizynski  · 技术社区  · 5 年前

    我试图将基于类的组件重构为使用钩子的函数式组件。在尝试获取登录状态时,我在gapi中正确使用了useState。

    只是想知道,我想得到什么:

    1) 初始化“auth”对象后获取其引用

    2) 弄清楚,如果我当前已登录

    3) 在屏幕上打印我的身份验证状态

    这里已经提出了一个类似的问题: LINK 但不幸的是,我没有将答案应用到我的案例中。

    以下是类组件:

    import React from "react";
    
    class GoogleAuth extends React.Component {
        componentDidMount() {
            window.gapi.load("client: auth2", () => {
                window.gapi.client
                    .init({
                        clientId: "myVerySecretAPI",
                        scope: "email"
                    })
                    .then(() => {
                        this.auth = window.gapi.auth2.getAuthInstance(); //this gets me acces to the auth object
                        this.setState({ isSignedIn: this.auth.isSignedIn.get() });
                    });
            });
        }
    
        renderAuthButton() {
            if (this.state.isSignedIn === null) {
                return <div>I dont know if we are signed in</div>;
            } else if (this.state.isSignedIn) {
                return <div>I am signed in!</div>;
            } else {
                return <div>I am not signed in</div>;
            }
        }
    
        render() {
            return <div>{this.renderAuthButton()}</div>;
        }
    }
    
    export default GoogleAuth;
    

    这是我重构的代码:

    import React, { useEffect, useState } from "react";
    
    const GoogleAuth = () => {
        const [ auth, setAuth ] = useState(null);
    
        useEffect(
            () => {
                window.gapi.load("client:auth2", () => {
                    window.gapi.client
                        .init({
                            clientId: "834243588921-gob95b7q7n3eids3fm8du8oharkv5od0.apps.googleusercontent.com",
                            scope: "email"
                        })
                        .then(() => {
                            setAuth(window.gapi.auth2.getAuthInstance());
                            auth({ isSignedIn: setAuth.isSignedIn.get() }); // this is the line where I get an error (please see below)
                        });
                });
            },
            [ auth ]
        );
    
        const renderAuthButton = (isSignedIn) => {
            if (isSignedIn === null) {
                return <div>I dont 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>;
            }
        };
    
        return <div>{renderAuthButton()}</div>;
    };
    
    export default GoogleAuth;
    

    我在chrome中收到一个错误,说:

    Uncaught TypeError:无法读取GoogleAuth.js中undefined的属性'get':16

    我知道,我错过了一点了解钩子使用的小东西。 欢迎任何帮助!

    1 回复  |  直到 5 年前
        1
  •  1
  •   Drew Reese    5 年前

    所以你基本上是在节省一些东西。第一个是 实际的 您从中获取的身份验证实例 window.gapi.auth2.getAuthInstance() 第二个是认证状态, isSignedIn 在你的代码中,你 setAuth 使用实例,但随后尝试调用已保存的实例,并向其传递一些新对象 已签名In 作为键,状态设置器作为值。这行不通。

    你可以先得到实例, 然后 使用实例从中获取auth状态以保存到您的状态中。您还应该使用一个空的依赖数组,以便在以下情况下只运行一次效果 GoogleAuth 安装。

    此外,您的 renderAuthButton 函数被定义为接受 已签名In 参数,但在返回时不传递任何东西。由于这是一个功能组件,因此您可以简单地省略参数并在作用域中使用状态值。

    const GoogleAuth = () => {
      const [isSignedIn, setIsSignedIn ] = useState(null);
    
      useEffect(
        () => {
          window.gapi.load("client:auth2", () => {
            window.gapi.client
              .init({
                clientId: "834243588921-gob95b7q7n3eids3fm8du8oharkv5od0.apps.googleusercontent.com",
                 scope: "email"
              })
              .then(() => {
                const authInstance = window.gapi.auth2.getAuthInstance();
                setIsSignedIn(authInstance.isSignedIn.get());
              });
          });
        },
        []
      );
    
      const renderAuthButton = () => {
        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>;
        }
      };
    
      return <div>{renderAuthButton()}</div>;
    };