0

First off, I don't know if I worded this correctly. I'm new to react and trying to learn how to use hooks properly.

When I submit, I get an "invalid email" error whether it is or isn't valid.

I want to be able to show an invalid email error if it is an invalid email and prefer it to go away upon successful submission of a valid email.

I'll eventually be adding some conditions to the password too.

import React, {useState} from 'react';
import {Link, useHistory} from 'react-router-dom';


const SignUp = () => {
  const history = useHistory();
  const [name, setName] = useState("")
  const [password, setPassword] = useState("")
  const [email, setEmail] = useState("")
  const [error, setError] = useState("")
  const [message, setMessage] = useState("")


  const PostData = ()=> {
    // adding regex to validate proper email
    if(!/^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w.-]+)+[\w\-._~:/?#[\]@!$&'()*+,;=.]+$/.test(email)){
      setError("Invalid email.")
      // added this to close out the whole process if there is an error
      return
    }
    fetch("/signup",{
      method:"post",
      headers:{
          "Content-Type":"application/json"
      },
      body:JSON.stringify({
          name,
          password,
          email,

      })
  }).then(res=>res.json())
    .then(data=>{
      if(data.error){
        setError(data.error)
      }
      else{
        setMessage(data.message)
        history.push('/signin')
      }
    }).catch(err=>{
      console.log(err)
    })
  }

  return(
    <div className="mycard">
      <div className="auth-card">
        <h2>Test</h2>
        <input 
        type="text"
        placeholder="name"
        value={name}
        onChange={(e)=>setName(e.target.value)}
        />
        <input 
        type="text"
        placeholder="email"
        value={email}
        onChange={(e)=>setEmail(e.target.value)}
        />
        <input 
        type="text"
        placeholder="password"
        value={password}
        onChange={(e)=>setPassword(e.target.value)}
        />
        <button className="btn" onClick={()=>PostData()} >
          Sign Up
        </button>

        {/* Show Error or Message */}
        { error && <div style={{color: "red"}}> {error}</div> }
        { message && <div style={{color: "green"}}> {message}</div> }

        <h5>
          <Link to="/signup">Already have an account?</Link>
        </h5>

      </div>
    </div>
  )

}

export default SignUp
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
andywalt
  • 109
  • 1
  • 13

2 Answers2

2

The regex you have does not validate an email address, but some sort of hyperlink. Use a different regular expression, or, even better, use type="email" on the input (inside a <form>) so that the browser validates it.

Another problem is that you're never clearing error, so if the email is invalid once on submission, the error won't go away. Clear error when the email field changes:

onChange={(e) => { setError(''); setEmail(e.target.value); }}
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • How do I say "I love you and thank you so much" in your language? Seriously, appreciate the feedback and you being nice about it. – andywalt Jan 01 '21 at 18:19
0

In addition to the answer above, once you have your regex expression. you can validate the PostData function using the following.

const PostData = ()=> {
    regex="regex expression"
    //the regex expression for email validation goes here
    if(regex.test(email){
    setTimeOut(()=>{
       setError("Invalid email.")
    }, 3000) //using this will ensure the error message gets cleared after 3 seconds

      }
      else {
      fetch(...)
      }
    }