Search code examples
javascriptreactjsuse-statereact-forms

React js - useState returns different values inside and outside of a onChange Form function


I would like to know why loginPassword.length and loginPasswordError is different inside and outside of loginFormPasswordHandler

import React, {useState} from 'react';
import './styles.css'

const App = () => {

  const [loginPassword, setLoginPassword] = useState('');
  const [loginPasswordError, setLoginPasswordError] = useState();
  const [submitController, setSubmitController] = useState(false);

  const loginFormSubmitHandler = (e) => {
    e.preventDefault();
  }



  const loginFormPasswordHandler = (e) => {
    setLoginPassword(e.target.value);
    setLoginPasswordError(loginPassword.length < 8);
    console.log('login password length is(inside):'+loginPassword.length+' and the state is '+loginPasswordError)
    loginPassword.length > 8 ? setSubmitController(true) : setSubmitController(false);
  }

  console.log('login password length is(outside):'+loginPassword.length+' and the state is '+loginPasswordError)

  return(
  <React.Fragment>
    <div className="form-wrapper">
      <form onSubmit={loginFormSubmitHandler}>
        <input className={`${loginPasswordError && 'error'}`} type="password" id="password" name="password" placeholder="Password" onChange={loginFormPasswordHandler} />
        <div className={`submit-btn ${submitController ? '' : 'disable'}`}>
          <input type="submit" />
        </div>
      </form>
    </div>
  </React.Fragment>
  );
}

export default App;

I know useState re-runs the entire code when the state is changed. But I can't understand this behavior. I am not sure whether this is a Javascript property or React property.


Solution

  • setState is asynchronous, meaning your login password and error state values might not update immediately after you run setLoginPassword and setLoginPasswordError.

    The other line below re-runs on every render, so it will output up to date values.

    console.log('login password length is(outside):'+loginPassword.length+' and the state is '+loginPasswordError)