[英]Getting this error “Invalid hook call. Hooks can only be called inside of the body of a function component.” inside a react functional component?
I am receiving this error "Invalid hook call. Hooks can only be called inside of the body of a function component."我收到此错误“无效的挂钩调用。挂钩只能在 function 组件的主体内部调用。” when I try and run my function.
当我尝试运行我的 function 时。 I am trying to run a script that generates a reCaptcha token the script is as follows:
我正在尝试运行一个生成 reCaptcha 令牌的脚本,该脚本如下:
This component should generate the token(this is where I get the error)
这个组件应该生成令牌(这是我得到错误的地方)
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])
}
Here within another component, I call the prior script component with an action type passed through but I get the react hook error mentioned(only showing relevant code snipets).
在另一个组件中,我使用传递的操作类型调用先前的脚本组件,但我得到了提到的反应钩子错误(仅显示相关的代码片段)。
import * as React from 'react'
import { RecaptchaGen } from '../../../components/_molecules/Recaptcha'
const onLoginClick = () => {
RecaptchaGen({ actionType: 'login' })
}
I presume the issue is the way I am calling/using the imported component but I can't find a solution?我认为问题是我调用/使用导入组件的方式,但我找不到解决方案?
You are using useEffect
hook inside regular js
function.您在常规
js
function 中使用useEffect
挂钩。
hooks
can only be called inside valid react component. hooks
只能在有效的反应组件内调用。 RepcaptchaGen
is not a react component because its not using react component specific things like returning some jsx
. RepcaptchaGen
不是一个反应组件,因为它不使用反应组件特定的东西,比如返回一些jsx
。
The name RecaptchaGen
would suggest it is a constructor function or component but it's neither. RecaptchaGen
这个名字暗示它是一个构造函数 function 或组件,但两者都不是。 it is a custom hook so should start with use
, for exampele: useRecaptchaGen.它是一个自定义钩子,所以应该从
use
开始,例如:useRecaptchaGen。
Here is how you can use it in your component:以下是如何在组件中使用它:
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);
};
The reason for this is that you aren't returning any code in your RecaptchaGen function.原因是您没有在您的 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.
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. If you want to fix this, add a return statement.
如果要解决此问题,请添加 return 语句。
I am not familiar with your specific use case, but a common pattern is to encapsulate some of the effect logic into a function that is returned by your custom hook, then any normal JS function (callback or not) can invoke that function.我不熟悉您的具体用例,但一种常见的模式是将一些效果逻辑封装到您的自定义钩子返回的 function 中,然后任何正常的 JS function(无论是否回调)都可以调用该ZC1C4F4252678C17893。
Rename RecaptchaGen
to useRecaptchaGen
so it can be used as a React hook.将
RecaptchaGen
重命名为useRecaptchaGen
,以便它可以用作 React 钩子。
Return a function to basically replace the second useEffect
callback.返回一个 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 }; }
In the component use the new hook and destructure generateRecaptcha
.在组件中使用新的钩子并解构
generateRecaptcha
。
const { generateRecaptcha } = useRecaptchaGen({ actionType: 'login' });
Invoke generateRecaptcha
in the onLoginClick
handler.在
onLoginClick
处理程序中调用generateRecaptcha
。
const onLoginClick = () => { generateRecaptcha(); }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.