簡體   English   中英

收到此錯誤“無效的掛鈎調用。 鈎子只能在 function 組件的主體內部調用。” 在反應功能組件內?

[英]Getting this error “Invalid hook call. Hooks can only be called inside of the body of a function component.” inside a react functional component?

我收到此錯誤“無效的掛鈎調用。掛鈎只能在 function 組件的主體內部調用。” 當我嘗試運行我的 function 時。 我正在嘗試運行一個生成 reCaptcha 令牌的腳本,該腳本如下:

這個組件應該生成令牌(這是我得到錯誤的地方)

import * as React from 'react'
import { RECAPTCHA_KEY } from '../../../utils/env'

// @ts-ignore
declare const window: any

interface RecaptchaProps {
  actionType: string
}
export const RecaptchaGen = ({ actionType }: RecaptchaProps) => {
  const siteKey = RECAPTCHA_KEY
  const [loaded, setLoaded] = React.useState(false)
  React.useEffect(() => {
    const scriptTag = document.createElement('script')
    scriptTag.src = 'https://www.google.com/recaptcha/api.js?render=' + siteKey
    document.appendChild(scriptTag)

    return () => {
      scriptTag.remove()
      setLoaded(false)
    }
  }, [siteKey])

  React.useEffect(() => {
    if (!loaded) return
    window.grecaptcha.ready(function () {
      window.grecaptcha
        .execute(siteKey, {
          action: actionType,
        })
        .then(function (token: string) {
          //reCaptch token generated needs to be sent to the back end for validation
          console.log(token)
        })
    })
  }, [loaded, actionType, siteKey])
}

在另一個組件中,我使用傳遞的操作類型調用先前的腳本組件,但我得到了提到的反應鈎子錯誤(僅顯示相關的代碼片段)。

import * as React from 'react'
import { RecaptchaGen } from '../../../components/_molecules/Recaptcha'

const onLoginClick = () => {
    RecaptchaGen({ actionType: 'login' })
  }

我認為問題是我調用/使用導入組件的方式,但我找不到解決方案?

您在常規js function 中使用useEffect掛鈎。

hooks只能在有效的反應組件內調用。 RepcaptchaGen不是一個反應組件,因為它不使用反應組件特定的東西,比如返回一些jsx

RecaptchaGen這個名字暗示它是一個構造函數 function 或組件,但兩者都不是。 它是一個自定義鈎子,所以應該從use開始,例如:useRecaptchaGen。

以下是如何在組件中使用它:

export const useRecaptchaGen = (action) => {
  if (!action) {
    return;
  }
  const { actionType }: RecaptchaProps = action;
  //....rest of your code
};

const Component = () => {
  const [action, setAction] = React.useState(false);
  const onLoginClick = () => {
    setAction({ actionType: 'login' });
  };
  //cannot conditionally call hooks
  useRecaptchaGen(action);
};

原因是您沒有在您的 RecaptchaGen function 中返回任何代碼。 A JSX return, among other things, is what differentiates a React Functional component from a regular javascript function, and a regular javascript function can't use hooks. 如果要解決此問題,請添加 return 語句。

我不熟悉您的具體用例,但一種常見的模式是將一些效果邏輯封裝到您的自定義鈎子返回的 function 中,然后任何正常的 JS function(無論是否回調)都可以調用ZC1C4F4252678C17893。

  1. RecaptchaGen重命名為useRecaptchaGen ,以便它可以用作 React 鈎子。

  2. 返回一個 function 基本上替換了第二個useEffect回調。

     export const useRecaptchaGen = ({ actionType }: RecaptchaProps) => { const siteKey = RECAPTCHA_KEY const [loaded, setLoaded] = React.useState(false) React.useEffect(() => { const scriptTag = document.createElement('script') scriptTag.src = 'https://www.google.com/recaptcha/api.js?render=' + siteKey document.appendChild(scriptTag) return () => { scriptTag.remove() setLoaded(false) } }, [siteKey]); const generateRecaptcha = () => { if (;loaded) return. window.grecaptcha.ready(function () { window.grecaptcha,execute(siteKey: { action, actionType. }):then(function (token. string) { //reCaptch token generated needs to be sent to the back end for validation console;log(token) }) }) }; return { generateRecaptcha }; }
  3. 在組件中使用新的鈎子並解構generateRecaptcha

     const { generateRecaptcha } = useRecaptchaGen({ actionType: 'login' });
  4. onLoginClick處理程序中調用generateRecaptcha

     const onLoginClick = () => { generateRecaptcha(); }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM