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

2024-01-07

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

仅仅 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>);
      }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将基于类的组件转换为钩子(gapi API) 的相关文章

随机推荐

  • 如果为空则隐藏表格行

    我的 JSP 中有一个表 当生成页面时 该表可以为空 我想知道是否有办法仅在它们中没有实际文本的情况下隐藏它们 这是它们的样子 table border 1 style padding left 4px tr td td tr table
  • 禁用单个(禁用)@Html.EditorFor 上的验证

    我读过 给定的执行方式似乎对于不同的操作 控制器具有不同的视图模型 在我看来 这有点矫枉过正 我想 Html EditorFor model gt model Ingredient Name new htmlAttributes new c
  • 如何将 Carbon AXUIElementRef 转换为 Cocoa NSWindow

    在我的项目中 我可以获得鼠标所在的窗口 并且我可以使用AXUIElementSetAttributeValue element kAXFrontmostAttribute kCFBooleanTrue 使窗口暂时处于顶层 所以我想将元素转换
  • 如何在 PrimeNG 15.4+ 中替换表头排序图标

    在最新版本的 PrimeNG 中 图标排序的方式发生了变化 他们曾经只是有一个i带有 CSS 类的标签 我可以在 CSS 中覆盖它以使用我公司的图标 但现在他们使用带有 SVG 的模板 我在他们的发行说明中看到如何覆盖菜单中的图标 例如下拉
  • git 提交目录

    我创建了一个存储库 并在本地将现有项目目录拖放到该存储库中 然后我做了类似 git add directory 的事情并提交并推送它 当我在 github 上查看我的存储库时 我看到的只是没有子文件夹 没有内容的目录 如何将该项目的所有文件
  • 如何将图库按钮添加到有意打开的相机中?

    在我的应用程序中 用户可以使用相机拍摄照片 我使用意图来启动它 Intent android provider MediaStore ACTION IMAGE CAPTURE 现在 当打开相机时 缺少图库按钮 该按钮允许用户从 SD 卡中选
  • 主导基线在 Firefox 中不起作用

    考虑以下示例 g transform translate 50px 50px dominant baseline central text anchor middle
  • 在 JavaScript 中分析 JSON 数据

    我并不是说这是一个完全聪明的想法 我认为 理想情况下 大量数据的计算应该在后端完成 但请幽默一下 我正在尝试从 JSON 源中提取视图数据并进行一些分析 给定以下数据源 group satellite 1 data label feed 1
  • 以编程方式更改标签属性

    问题是我需要以编程方式更改标签字体粗细和字体样式 但似乎没有任何效果 这是我到目前为止所尝试的 label FontWeight FontWeight FromOpenTypeWeight 99 对于 label FontStyle 我不知
  • 使用 Python 创建 2 人游戏

    我的朋友向我提出挑战 要求我制作一个我们可以互相对战的流行游戏 战舰 的版本 如果你不了解这款游戏 那其实并不重要 因为对我来说 困难的部分不是制作游戏 而是弄清楚我们如何通过计算机相互对战 我之前制作过同样的游戏 只针对一名玩家 我使用的
  • 如何在rails 4中的单个rails应用程序中访问多个数据库?

    我是 Rails 新手 不知道如何在 Rails 单个应用程序中访问多个数据库 我会这样尝试 配置 数据库 yml default default adapter mysql2 encoding utf8 pool 5 username r
  • R:按字母数字对数据框进行排序

    我有一个数据框 它存储每个模型的计数值 型号名称是字母数字 然后 我使用 ggplot2 生成条形图 其中 x 轴为模型 y 轴为计数 我想订购我的 x 轴 x 轴在数据框中和图中的 x 轴中显示如下 我想对其进行正确排序 例如 M 1 M
  • 如何强制将一段文本设置为“direction rtl”段落内的“direction ltr”

    因此 电话号码始终是ltr 从左到右 在多语言网站上工作时 我需要在具有方向 rtl 的文本段落中插入电话号码 带有 前缀和用 分隔的数字 当然对于相关语言 所以我有这样的事情 ltr test direction ltr rtl test
  • cout 和 printf 适用于内置调试而非发布的 Dll

    我构建了一个 DLL 通常通过 SetWindowHookEx 注入到控制台应用程序中 DLL 将信息输出到控制台非常重要 我一直在使用 std cout 执行此操作 DLL 已接近完成 直到我尝试在发布模式下构建 DLL 这使得所有 co
  • 调试 C 代码

    有人可以告诉我我的代码有什么问题以及为什么它会产生这个输出 Code int main unsigned num char response do printf Please enter a positive integer greater
  • 禁用属性的正确值是多少?

    的正确值是多少disabled文本框或文本区域的属性 我以前见过使用以下内容
  • 如何根据环境实现cucumber场景不同的数据

    我在不同环境中执行 cucumber jvm 场景时遇到问题 场景的特征文件中包含的数据属于一个环境 为了在不同的环境中执行场景 我需要根据要执行的环境更新功能文件中的数据 例如 在以下场景中 我将搜索条件包含在功能文件中 搜索条件对于 Q
  • Objective-C - 弱属性 - getter autoreleases(自动引用计数)

    我有疑问weakARC 中的属性 自动引用计数 我的理解 如有错误请指正 weak属性的行为类似于assign属性 但当该属性指向的实例被销毁时 ivar 会指向 nil 问题 我只是觉得吸气剂weak属性保留和自动释放 它不是应该像 ge
  • 动态添加的表行不会触发单击事件

    我有一个空表 我使用以下方法通过 jQuery 添加行 table gt tbody last append tr td symbol Code1 td td symbol Code2 td td symbol Code3 td tr 一切
  • 将基于类的组件转换为钩子(gapi API)

    我有这个基于类的组件 使用gapi Google Auth API来呈现按钮并且它可以工作 import React from react class GoogleAuth extends React Component state isS