React Hooks:在验证时实例化状态挂钩错误:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用
Posted
技术标签:
【中文标题】React Hooks:在验证时实例化状态挂钩错误:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用【英文标题】:React Hooks: Instantiating state hooks on validation Error: Invalid hook call. Hooks can only be called inside of the body of a function component 【发布时间】:2021-11-14 16:02:24 【问题描述】:我收到以下错误,不确定在箭头函数内实例化反应挂钩时我做错了什么:
错误:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用。这可能是由于以下原因之一:
-
您可能有不匹配的 React 版本和渲染器(例如 React DOM)
您可能违反了 Hooks 规则
您可能在同一个应用程序中拥有多个 React 副本
有关如何调试和解决此问题的提示,请参阅 https://reactjs.org/link/invalid-hook-call。
这是我的代码 sn-p:(这是一个验证反应 js 文件,它返回一个错误状态(如果有的话),并且在调用方法中它期待另一个状态错误):
从 'react' 导入 React, useState, useEffect; 从'axios'导入axios;
const [errors, setErrors] = useState();
const checkUserExists = async (phone) =>
console.log('Inside CheckUserExists')
let isUserExist = false;
let formData = new FormData();
formData.append('phone', phone);
const response = await axios.post('http://localhost:3001/doesUserExistByPhone', formData).then(response=>
isUserExist = false;
console.log('Success response: ', response)
).catch(errorResponse=>
console.log('Error response: ', errorResponse)
isUserExist = true;
setErrors(
...errors, phone: 'User Already exist, u know?'
)
)
return isUserExist;
const patternName = new RegExp('^[a-zA-Z ]3,20$')
const patternPhone = new RegExp('^[0-9]9,10$')
const patternEmail = new RegExp('^[a-zA-Z0-9._:$!%-]+@[a-zA-Z0-9.-]+.[a-zA-Z]$')
const patternPassword = new RegExp('(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])(?=.8,)')
if(!values.name || !patternName.test(values.name))
//errors.name="Please enter a valid name"
if(!values.phone || !patternPhone.test(values.phone))
//errors.phone="Please enter a valid Phone number of 9-10 digits"
if(!values.email || !patternEmail.test(values.email))
//errors.email="Please enter a valid email address"
if(!values.password || !patternPassword.test(values.password))
//errors.password="Please enter a strong password to continue. A strong password has: Atleast 8 characters in length, 2 letters in upper case, 1 special character (!@#$&*), 2 number (0-9), 3 letters in lower case"
if(!values.isTermsAndConditionsAccepted)
//errors.isTermsAndConditionsAccepted = "Please Accept the Terms and conditions"
//Check if the user already exist
if(values.phone)
console.log('Inside if Values.phone is not NULL... will check if user exist...')
checkUserExists(values.phone)
console.log('Errors found before creating user: ', errors);
return errors;
export default ValidateRegister```
【问题讨论】:
【参考方案1】:确保所有的钩子(useState、useEffect...)都在 checkUserExists 函数中
【讨论】:
这对我不起作用,因为我需要在 checkUserExists 方法之外插入错误状态。我也在验证其他参数,如果有任何错误,则插入错误状态【参考方案2】:您是否正在使用 const ValidateRegister = () => 来包装您发布的所有内容?看来您没有使用 react 组件,或者您正在尝试将组件用作函数 util,因此您不能使用 const [errors, setErrors] = useState(); 您可以创建一个名为 useCheckUserList 的自定义钩子,带有错误和 setError 状态并返回 checkUserExists 和错误状态,然后将其导入到您的组件中。
import useState from 'react'
export const useCheckUserList = () =>
const [errors, setErrors] = useState();
const checkUserExists = async (phone) =>
console.log('Inside CheckUserExists')
let isUserExist = false;
let formData = new FormData();
formData.append('phone', phone);
const response = await axios.post('http://localhost:3001/doesUserExistByPhone', formData).then(response=>
isUserExist = false;
console.log('Success response: ', response)
).catch(errorResponse=>
console.log('Error response: ', errorResponse)
isUserExist = true;
setErrors(
...errors, phone: 'User Already exist, u know?'
)
)
return isUserExist;
return errors, checkUserList;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
在您要使用它的文件中,只需导入 useCheckUserList,然后执行以下操作: const errors, checkUserList = useCheckUserList() 现在您可以使用 checkUserList 函数和错误状态了。
这只是一个示例,您也可以将所有代码放入自定义挂钩中,然后在 ValidateRegister 组件中使用。
【讨论】:
我该怎么做?我需要创建一个类吗?我已经在箭头函数中嵌入了钩子,这还不足以作为 React 组件吗? 如果可能请举个例子? 我编辑了这篇文章,给你一个例子,希望对你有帮助【参考方案3】:您必须将“error and setError”传递给您调用或导入该组件的 ValidateRegister 组件,例如:
<ValidateRegister error=error setError=setError />
// and take it as props in ValidateRegister component like
const ValidateRegister = (error, setError) =>
//your code
【讨论】:
以上是关于React Hooks:在验证时实例化状态挂钩错误:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用的主要内容,如果未能解决你的问题,请参考以下文章
错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。 (React-hooks React-native)
错误 无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用