0

I want to show the username in the alert box. But so far it's not working. Here is my code:

function App() {

  const [nameInForm, setNameInForm] = useState("");

  const [username, setUserName] = useState("");

  const inputName = (event) => {
       setNameInForm(event.target.value);
  }

  const handleSubmit = () => {
       setUserName(nameInForm);
       alert("Welcome " + username);
  }

  return (
     <>
      <form onSubmit={handleSubmit}>
        <input type="text" value={nameInForm} onChange={inputName} />
        <button type="submit"> Login </button>
      </form>
     </>
  );
 }

If I don't use the form tag and use onClick={handleSubmit} on the button still the code does not work.

Boidurja Talukdar
  • 676
  • 2
  • 21
  • 42
  • 1
    State updates are asynchronous. Alert is being called before the state of userName is set. You can solve this by setting the username in the onChange function. – kevin Jul 08 '21 at 08:33
  • Does this answer your question? [useState set method not reflecting change immediately](https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately) – Yoshi Jul 08 '21 at 08:36
  • Ref: [useState set method not reflecting change immediately](https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately) and [How do JavaScript closures work?](https://stackoverflow.com/questions/111102/how-do-javascript-closures-work). Note: It has absolutely nothing to do with state updates being asynchronous. – Yoshi Jul 08 '21 at 08:38

2 Answers2

1

Setting state is kinda async operation. You can not use the new state value on the next line of code in console.log() or alerts etc... In your example, you already have the username in "nameInForm" state, you can use it

const handleSubmit = () => {
  setUserName(nameInForm);
  alert("Welcome " + nameInForm);
}

either "username" and useEffect hook can be used which is nice way to watch state changes:

//the function is updating state:
const handleSubmit = () => {
  setUserName(nameInForm);
}
// the useEffect hook shows new state after it has been updated
useEffect(() => {
  alert("Welcome " + username);
}, [username])
Tarukami
  • 1,160
  • 5
  • 8
0

You should not call setUserName in handleSubmit. As setUserName is asynchronous it will be resolved on next render so you should do

const handleSubmit = () => {
       alert("Welcome " + nameInForm);
}
Matthieu Bouxin
  • 127
  • 1
  • 5