Reputation: 81
I get the following error, not sure what am I doing wrong in instantiating the react hooks inside a arrow functionion:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
This is my code snippet: (It's a validation react js file which returns a state of errors if any, and in the calling method it's expecting another state error):
import React, {useState, useEffect} from 'react'; import axios from '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```
Upvotes: 1
Views: 615
Reputation: 474
you have to pass "error and setError" to your ValidateRegister Component from where you called or import that component like:
<ValidateRegister error={error} setError={setError} />
// and take it as props in ValidateRegister component like
const ValidateRegister = ({error, setError}) => {
//your code
}
Upvotes: 0
Reputation: 974
Are you doing const ValidateRegister = () =>{} to wrap all what you post? It seems that you are not using a react component, or you are trying to use a component as a function util, so you cant use const [errors, setErrors] = useState({}); You can create a custom hook called useCheckUserList, with the error and setError state and return the checkUserExists and the error state, and import it to your component.
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>
And in the file where you are going to use it just import the useCheckUserList, and do the following: const {errors, checkUserList} = useCheckUserList() Now you can youse the checkUserList function and errors state.
This is just an example, you can also take all your code into a custom hook and then use it in the ValidateRegister component.
Upvotes: 0
Reputation: 158
make sure that all your hook (useState, useEffect...) are inside the checkUserExists function
Upvotes: 0