Why I am getting wrong error count in Object.keys(formErrors).length?

Viewed 25

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!

0 Answers
Related