I am creating a next js app and trying to validate the form. But I am getting the wrong error count. I am getting 0 when I am clicking the Join (submit) button for the first time when the field is empty. Then when I am clicking the button again I am getting 1.
Here is my code -
import React, { useRef, useState, useEffect } from 'react';
import Tippy from '@tippyjs/react';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { SubscribeToast } from './SubscribeToast';
import { BounceLoader } from 'react-spinners';
function Subscribe() {
const router = useRouter();
const [isEmailInvalid, setIsEmailInvalid] = useState(false);
const [isEmailEmpty, setIsEmailEmpty] = useState(false);
const [showError, setShowError] = useState(false);
const ref = useRef();
const initialValues = { email: '' };
const [formValues, setFormValues] = useState(initialValues);
const [formErrors, setFormErrors] = useState({});
const [isSubmit, setIsSubmit] = useState(false);
const handleChange = (e) => {
const { name, value } = e.target;
validate(formValues);
setFormValues({ ...formValues, [name]: value });
};
const handleSubmit = (e) => {
e.preventDefault();
setIsSubmit(true);
setFormErrors(validate(formValues));
console.log(Object.keys(formErrors).length)
// if (Object.keys(formErrors).length === 0){
// // document.getElementById("subscribeForm").classList.add("opacity-70","select-none");
// // setTimeout(() => {
// // }, 6000);
// router.push('/confirmation');
// }
};
const validate = (values) => {
const errors = {};
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i;
if (!values.email || values.email === "") {
errors.email = 'Email is required!';
setIsEmailEmpty(true);
setIsEmailInvalid(false);
setShowError(true);
} else if (!regex.test(values.email) && values.email !== "") {
errors.email = 'Invalid Email!';
setIsEmailEmpty(false);
setIsEmailInvalid(true);
setShowError(true);
} else {
setIsEmailEmpty(false);
setIsEmailInvalid(false);
setShowError(false);
}
return errors;
};
return (
<>
<form onSubmit={handleSubmit} id="subscribeForm">
<div className="md:flex">
{isEmailEmpty && (
<Tippy
content="Email is required"
visible={showError}
reference={ref}
/>
)}
{isEmailInvalid && (
<Tippy
content="Invalid email address"
visible={showError}
reference={ref}
/>
)}
<div className="relative">
<input
ref={ref}
name="email"
type="email"
className={`input-box ${
( ( isEmailEmpty || isEmailInvalid ) && 'border-[#DA0000]')
} `}
placeholder="Your Email"
value={formValues.email}
onChange={handleChange}
onKeyUp={handleChange}
/>
{( isEmailEmpty || isEmailInvalid ) && (
<div className="absolute top-3.5 right-8">
<Image
src="/alert.svg"
width={15}
height={15}
alt="Alert"
/>
</div>
)}
</div>
<button type="submit" className="btn">
Join Us
</button>
</div>
</form>
</>
);
}
export default Subscribe;
Kindly tell me where am I doing the mistake so that I can understand and write the code more efficiently. I am trying to learn react and next js. Thank you!