skip to Main Content

I am trying to create a hook that hides my form after it has been submitted whilst trying to show the message sent image afterwards, but I can’t seem to get the form to disappear.

so far I have tried this:

const ContactForm = () => {
  ...
  const [show, setShow] = React.useState(true);

const handleSubmit = (e) => {
  ...
}

My content is here:

return (
 <>
  {show ? (
          <form onSubmit={handleSubmit} className='email-form'>
            <div className='form'>
              <input .../>
              <input .../>
              <textarea .../>
            </div>
            <button
              disabled={!name || !email || !message}
              onClick={() => {
                handleSubmit();
                setShow(!show);
                if(!handleSubmit) {
                  setShow(false)
                } else {
                  setShow(true)
                }
              }}
             type="submit"
             className='send-btn'
            >
              <span>Send Message</span>
           </button>
   
       <div className='message-sent'>
          <CircleCheckBig className='sent-tick' strokeWidth={1} size={200}/>
          <p className='sent-message'>Message Sent</p>
        </div>
      </form>) : null}
  </>

I want the 'email-form' to disappear when the ‘Send Message’ button is clicked and to be replaced with the message-sent <div>. Any ideas on how to achieve this?

I tried an if statement and hooks mainly.

2

Answers


  1. Get rid of this code entirely:

    if(!handleSubmit) {
      setShow(false)
    } else {
      setShow(true)
    }
    

    You’ve defined handleSubmit as a function, so interpreting it as a boolean (1) makes no sense and (2) will always be truthy (which you negate to false). Since the result is always the same, you’re always invoking the else block and always setting show to true.

    Since the two lines of code before this structure already:

    1. Invoke the function
    2. Toggle the state value

    Then you don’t need the rest of this structure anyway. It’s not clear where you got this or what you expect it to do and why. But what is is doing is explicitly always setting show to true.


    and to be replaced with the message-sent <div>

    Currently both the <form> and the <div> are either both shown or both not shown, because they’re both in the same part of your ternary conditional expression:

    {show ? (
      <form>
        <!-- form contents -->
        <div>
          <!-- div contents -->
        </div>
      </form>) : null}
    

    Separate them. Specifically, make them the two different results of your ternary conditional expression:

    {show ? (
      <form>
        <!-- form contents -->
      </form>
    ) : (
      <div>
        <!-- div contents -->
      </div>
    )}
    

    That way you’re showing one or the other, not both or neither.

    Login or Signup to reply.
  2. Your mistake is that your div, where your message is at, is inside the form tag. You have to move it outside and replace it with null:

    return (
     <>
      {show ? (
              <form onSubmit={handleSubmit} className='email-form'>
                <div className='form'>
                  <input .../>
                  <input .../>
                  <textarea .../>
                </div>
                <button
                  disabled={!name || !email || !message}
                  onClick={() => {
                    handleSubmit();
                    setShow(!show);
                    if(!handleSubmit) {
                      setShow(false)
                    } else {
                      setShow(true)
                    }
                  }}
                 type="submit"
                 className='send-btn'
                >
                  <span>Send Message</span>
               </button>
       
          </form>) : (
           <div className='message-sent'>
              <CircleCheckBig className='sent-tick' strokeWidth={1} size={200}/>
              <p className='sent-message'>Message Sent</p>
            </div>)}
      </>
    

    Furthermore your onClick function inside your button is a bit "weird". What you are trying to achieve is that you only want the message inside the div to be seen, if the button was pressed by checking if handleSubmit was called. I would rather delete the whole onClick functionality and move the setShow(true) to the handleSubmit function. Because if you click on the button, the onSubmit event is called inside the form automatically (this is because by standard the HTML button is from type submit.) So you can do it like this:

    const handleSubmit = () => {
        // ... your logic here
        setShow(false);
    };
    
        return (
         <>
          {show ? (
                  <form onSubmit={handleSubmit} className='email-form'>
                    <div className='form'>
                      <input .../>
                      <input .../>
                      <textarea .../>
                    </div>
                    <button
                      disabled={!name || !email || !message}
                     className='send-btn'
                    >
                      <span>Send Message</span>
                   </button>
           
              </form>) : (
               <div className='message-sent'>
                  <CircleCheckBig className='sent-tick' strokeWidth={1} size={200}/>
                  <p className='sent-message'>Message Sent</p>
                </div>)}
          </>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search