javascript – Why does the Form disappear on trying to type data in the input fields?

I have a form in a React app. The form opens only after clicking the chat with us button and should close only after either clicking submit or the background. However, it is closing every time I begin to type in something. I’m unsure what is causing this behaviour.

Here is the code for my form: Form.js

import React, { useState } from 'react';
import {
    FormColumn,
    FormWrapper,
    FormInput,
    FormSection,
    FormRow,
    FormTitle,
    FormLabel,
    FormInputRow,
    FormButton,
    FormMessage,
} from './FormStyles';
import { Container } from '../../globalStyles';
import validateForm from './validateForm';

const Form = () => {
    const [name, setName] = useState('');
    const [email, setEmail] = useState('');
    const [subject, setSubject] = useState('');
    const [message, setMessage] = useState('');
    const [error, setError] = useState(null);
    const [success, setSuccess] = useState(null);

    const handleSubmit = (e) => {
        e.preventDefault();
        const resultError = validateForm({ name, email, subject, message });

        if (resultError !== null) {
            setError(resultError);
            return;
        }
        setName('');
        setEmail('');
        setSubject('');
        setMessage('');
        setError(null);
        setSuccess('Message was sent!');
    };

    const messageVariants = {
        hidden: { y: 30, opacity: 0 },
        animate: { y: 0, opacity: 1, transition: { delay: 0.2, duration: 0.4 } },
    };

    const formData = [
        { label: 'Name', value: name, onChange: (e) => setName(e.target.value), type: 'text' },
        { label: 'Email', value: email, onChange: (e) => setEmail(e.target.value), type: 'email' },
        {
            label: 'Subject',
            value: subject,
            onChange: (e) => setSubject(e.target.value),
        },
        {
            label: 'Message',
            value: message,
            onChange: (e) => setMessage(e.target.value),
        },
    ];

    return (
        <FormSection>
            <Container>
                <FormRow>
                    <FormColumn>
                        <FormTitle>Sign Up</FormTitle>
                        <FormWrapper onSubmit={handleSubmit}>
                            {formData.map((el, index) => (
                                <FormInputRow key={index}>
                                    <FormLabel>{el.label} *</FormLabel>
                                    <FormInput
                                        type={el.type}
                                        value={el.value}
                                        onChange={el.onChange}
                                    />
                                </FormInputRow>
                            ))}

                            <FormButton type="submit">Let's talk</FormButton>
                        </FormWrapper>
                        {error && (
                            <FormMessage
                                variants={messageVariants}
                                initial="hidden"
                                animate="animate"
                                error
                            >
                                {error}
                            </FormMessage>
                        )}
                        {success && (
                            <FormMessage
                                variants={messageVariants}
                                initial="hidden"
                                animate="animate"
                            >
                                {success}
                            </FormMessage>
                        )}
                    </FormColumn>
                </FormRow>
            </Container>
        </FormSection>
    );
   };

export default Form;

Modal.js which handles everything: ( I think something’s wrong here but can’t figure out what)

import React, { useRef, useEffect, useCallback } from "react";
import { AnimatePresence } from "framer-motion";
import { Background, CloseModalButton, ModalWrapper } from "./ModalStyles";
import Form from "../Form/Form";

const Modal = ({ showModal, toggleModal }) => {
  const modalRef = useRef();

  const closeModal = (e) => {
    if (modalRef.current === e.target) {
      toggleModal();
    }
  };

  const keyPress = useCallback(
    (e) => {
      if (e.key && showModal) {
        toggleModal();
      }
    },
    [showModal, toggleModal]
  );

  useEffect(() => {
    document.addEventListener("keydown", keyPress);

    return () => document.removeEventListener("keydown", keyPress);
  }, [keyPress]);

  const backgroundVariants = {
    initial: {
      opacity: 0,
    },
    animate: {
      opacity: 1,
      transition: {
        duration: 0.4,
      },
    },
  };

  const modalVariants = {
    initial: {
      opacity: 0,
      y: 200,
    },
    animate: {
      opacity: 1,
      y: 0,
      transition: {
        duration: 0.4,
        type: "spring",
        stiffness: 100,
      },
    },

    exit: {
      y: -200,
      opacity: 0,
    },
  };

  return (
    <AnimatePresence>
      {showModal && (
        <Background
          variants={backgroundVariants}
          animate="animate"
          initial="initial"
          onClick={closeModal}
          ref={modalRef}
          exit={{
            opacity: 0,
          }}
        >
          <ModalWrapper
            variants={modalVariants}
            animate="animate"
            initial="initial"
            exit={{
              opacity: 0,
              y: "-100vh",
            }}
          >
            <Form></Form>
            <CloseModalButton aria-label="Close modal" onClick={toggleModal} />
          </ModalWrapper>
        </Background>
      )}
    </AnimatePresence>
  );
};

export default Modal;

Finally the Hero section where the chat with us button is located:

import React, { useEffect, useState } from 'react';
import { FiMail } from 'react-icons/fi';
import {
    HeroSection,
    Heading,
    HeroText,
    ButtonContainer,
    HeroButton,
    HeroImage,
    HeroContent,
    ButtonWrapper,
} from './HeroStyles';
import { useInView } from 'react-intersection-observer';
import Modal from '../Modal/Modal';

const Hero = () => {
    const [showModal, setShowModal] = useState(false);
    const dragConstraints = { top: 0, bottom: 0, right: 0, left: 0 };

    const toggleModal = () => {
        if (!showModal) {
            document.body.style.overflow = 'hidden';
        } else {
            document.body.style.overflow = 'visible';
        }

        setShowModal(!showModal);
    };

    const variants = {
        hover: {
            y: 15,
            transition: {
                yoyo: Infinity,
                duration: 0.6,
            },
        },
    };
    const { ref, inView } = useInView({
        rootMargin: '-100px',
    });

    useEffect(() => {
        console.log(inView);
    }, [inView]);

    return (
        <>
            <HeroSection id="hero">
                
                    <ButtonContainer ref={ref}>
                        <ButtonWrapper>
                            <HeroButton onClick={toggleModal}  className={inView ? '' : 'corner'}>
                                {inView ? (
                                    <> Chat with us</>
                                ) : (
                                    <FiMail color="white" size="2.3rem" />
                                )}
                            </HeroButton>
                        </ButtonWrapper>
                    </ButtonContainer>
                
            </HeroSection>
            <Modal showModal={showModal} toggleModal={toggleModal} />
        </>
    );
};

export default Hero;

Leave a Comment