首页 > 解决方案 > 在 React 中将类组件转换为功能组件

问题描述

我正在尝试采用允许用户完成 ReCaptcha 的类组件,并且我正在尝试将其重写为功能组件。我遇到了一些麻烦,所以如果你们能告诉我我犯了什么错误,我将不胜感激!如果您需要查看我用于recaptcha 的节点包,这里有一个链接:https ://www.npmjs.com/package/react-recaptcha-google 。我的假设是我的 useRef() 钩子不知何故出错了,但老实说我不确定。

我在我的版本和以前版本的结果中遇到了一些差异。

第一个区别是,当页面加载时,我的函数verifyCallback(recaptchaToken)立即运行,因此控制台打印“TOKEN:未定义”,而在原始页面中没有打印(我假设也不运行)

第二个区别是当用户完成重新验证时,据verifyCallback(recaptchaToken)我所知,我的函数不会被调用,因此我的令牌不会打印到控制台,而在原始版本中它会打印到控制台。

这是原始的类组件。用户完成 ReCaptcha 并出现复选标记后,变量“recaptchaToken”将打印到控制台。


import React from 'react'
import { ReCaptcha } from 'react-recaptcha-google'

class Recaptcha extends React.Component {
constructor(props, context) {
    super(props, context);
    this.onLoadRecaptcha = this.onLoadRecaptcha.bind(this);
    this.verifyCallback = this.verifyCallback.bind(this);
  }
  
  componentDidMount() {
    if (this.captchaDemo) {
        console.log("started, just a second...")
        this.captchaDemo.reset();
    }
  }

  onLoadRecaptcha() {
      if (this.captchaDemo) {
          this.captchaDemo.reset();
      }
  }

  verifyCallback(recaptchaToken) {
    console.log("TOKEN:", recaptchaToken);
  }

  render() {
    return (
      <div>
        <ReCaptcha
            ref={(el) => {this.captchaDemo = el;}}
            size="normal"
            data-theme="dark"
            render="explicit"
            sitekey=[site_key]
            onloadCallback={this.onLoadRecaptcha}
            verifyCallback={this.verifyCallback}
        />
        <span id="recaptcha-error" className="signup-error"></span>
      </div>
    );
  };
}

export default Recaptcha;

这是我重写的代码:

import React, {useEffect, useRef} from 'react'
import { ReCaptcha } from 'react-recaptcha-google'

export default function NewRecaptcha() {
    const captchaDemo = useRef();

    useEffect(() => {
        if(captchaDemo.current) {
            console.log("started, just a second...")
            captchaDemo.current.reset();
        }
    }, [captchaDemo])

    function onLoadRecaptcha() {
        if(captchaDemo.current) {
            captchaDemo.current.reset();
        }
    }

    function verifyCallback(recaptchaToken) {
        console.log("TOKEN:", recaptchaToken);
    }

    return (
        <div>
            <ReCaptcha
                ref={captchaDemo}
                size="normal"
                data-theme="dark"
                render="explicit"
                sitekey=[site_key]
                onloadCallback={onLoadRecaptcha()}
                verifyCallback={verifyCallback()}
            />
            <span id="recaptcha-error" className="signup-error"></span>
        </div>
    )
}

标签: reactjsreact-functional-component

解决方案


第一个区别是,当页面加载时,我的函数 verifyCallback(recaptchaToken) 立即运行,因此控制台打印“TOKEN:未定义”,而在原始页面中没有打印(我假设也不运行)

这是因为您正在传递verifyCallback()给 ReCaptcha,而不是verifyCallback调用该函数,并且在第一次渲染时传递结果。您可以通过verifyCallback像这样传递来解决此问题:

<ReCaptcha
  // other props
  onloadCallback={onLoadRecaptcha}
  verifyCallback={verifyCallback}
/>

第二个区别是当用户完成 recaptcha 时,据我所知,我的函数 verifyCallback(recaptchaToken) 不会被调用,因此我的令牌不会打印到控制台,而在原来的情况下它会打印到控制台。

这基本上是出于相同的原因。您应该将函数本身向下传递给 ReCaptcha 组件,而不是调用函数并将结果向下传递。


推荐阅读