Home > Mobile >  matching passwords with react hooks is not working after onchange
matching passwords with react hooks is not working after onchange

Time:11-18

I'm trying change error state after two password states become equal. But when I finish typing passwords onchange doesn't execute it requires to execute one more time.

*on using onkeyup events It works but i dont if its a good practice or not. I've also tried making it a timeout function but it didn't help either

Here are my functions.

const [password, setPassword] = useState('')
const [password2, setPassword2] = useState('')
const [passError, setPerror] = useState(false)

const handleChange = (event) => {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

    console.log(name  "  "  value);
    

    if(name == 'username') setUsername(value);
    if(name == 'email') setEmail(value);
    if(name == 'pass') setPassword(value);
    if(name == 'pass2') setPassword2(value);

    setTimeout(()=>checkPass(), 2000);
    
}

const checkPass = () => {
    if (password != password2) setPerror(true);
    else setPerror(false);
    console.log(passError)
}

Here is my html.

<input type="password" className="form-control" name="pass"  placeholder="Password" required=""  
        value={password}  onChange={handleChange} onKeyUp={handleChange} style={{marginBottom: 0}} />      

        <input type="password" className="form-control" name="pass2"  placeholder="Confirm Password" required=""
        value={password2}  onChange={handleChange} />  

        { passError && <p className='alert-danger'>Password does not match!</p>} 

CodePudding user response:

Issue

The issue here is that you are attempting to reference state that hasn't updated yet. It actually doesn't matter how long the timeout you set is, the "instance" of checkPass with the unupdated state is what is enqueued and closed over in the callback scope. It will always and forever be the state value at the time the callback was enqueued.

Solution

Instead of using a timeout to check the state after it updates, use an useEffect hook with a dependency on the password state values to call checkPass and do the validation. Similarly move the logging of the passError state to an useEffect hook.

useEffect(() => {
  checkPass();
}, [password, password2]);

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

const handleChange = (event) => {
  const { checked, name, type, value } = event.target;
  const newValue = type === 'checkbox' ? checked : value;

  if (name === 'username') setUsername(newValue);
  if (name === 'email') setEmail(newValue);
  if (name === 'pass') setPassword(newValue);
  if (name === 'pass2') setPassword2(newValue);
}

const checkPass = () => setPerror(password !== password2);
  • Related