-2

I have to click log in twice before it chacks the data. Can someone help why?

I'm creating a forum website and on my log-in page the user has to click the button twice before it the code validates and responds to the given data.

here is my handle submit which is triggered on button click.

const [values,setValues] =useState({
        email: '',
        password: ''
    })
    const navigate =useNavigate();
    const [errors, setErrors] = useState({})
    const handleInput = (e) => {
        setValues(prev => ({...prev, [e.target.name]: [e.target.value]}))
    }

const handleSubmit = (e) => {
        e.preventDefault()
        setErrors(Validation(values))
        if(errors.password === "" && errors.email === ""){
            axios.post('http://localhost:8081/login', values)
            .then(res => {
                    if(res.data.errorMessage ==='Success'){
                        navigate('/dashboard');
                    }
                    else{
                        console.log(res.data.errorMessage);
                    }
            })
            .catch(err => console.log(err));
            
        }
        
    };

PS validation returns error messages when spots are not filled properly

I'm new to nodejs and react so if anyone could explain it would be a huge help!

  • Can you include the declarations for `errors`, `setErrors`, and `Validation`? My best guess at the moment is that it's related to this issue: https://stackoverflow.com/questions/54069253/the-usestate-set-method-is-not-reflecting-a-change-immediately – Dennis Kats May 28 '23 at 14:42

1 Answers1

0

As I mentioned in my comment, my best guess is that this is related to The useState set method is not reflecting a change immediately. In your case, you are trying to access the properties on errors immediately after calling setErrors. However, not only will setErrors execute asynchronously, but its new value won't even be accessible from the current closure. Specifically, handleSubmit becomes what is known as a "stale closure" because errors still references the initial empty object {}. Only after rerendering does handleSubmit get redefined with the new error values; that's why it takes 2 clicks.

To fix your case, you just need to give yourself synchronous access to the new errors, which can be done simply by storing it in a local variable, like so:

const handleSubmit = (e) => {
        e.preventDefault()
        const newErrors = Validation(values);
        setErrors(newErrors)
        if(newErrors.password === "" && newErrors.email === ""){
            axios.post('http://localhost:8081/login', values)
            .then(res => {
                    if(res.data.errorMessage ==='Success'){
                        navigate('/dashboard');
                    }
                    else{
                        console.log(res.data.errorMessage);
                    }
            })
            .catch(err => console.log(err)); 
        }  
    };
Dennis Kats
  • 2,085
  • 1
  • 7
  • 16