Home > Back-end >  Can I await the update function of the useState hook
Can I await the update function of the useState hook

Time:08-18

I am building an app to understand the useState hook. This app simply has a form for entering username. I am trying to save the entered username. So, I have used react useState. And I tried to await the updating function of the useState in the event handler.

 const usernameChangeHandler = async (event) => {
    await setEnteredUsername(event.target.value);
    console.log(enteredUsername, enteredAge);
 
  };

And when I tried to log the username it doesn't show us the current state but the previous state. Why?

CodePudding user response:

That's exactly what useEffect should be used for. For example:

const [ enteredUsername, setEnteredUsername ] = useState('');

useEffect(() => { 
  // Do something when enteredUsername is changed
}, [ enteredUsername ]);

<MyInput
  value={enteredUsername}
  onKeyPress={(e) => setEnteredUsername(e.target.value)}
/>

CodePudding user response:

const usernameChangeHandler = async (event) => {
  await setEnteredUsername(event.target.value);
  console.log(enteredUsername, enteredAge); 
};

enteredUsername is never going to change. It's a closure variable that's local to this single time you rendered the component. It's usually a const, but even if it was made with let, setEnteredUsername does not even attempt to change its value. What setEnteredUsername does is ask react to rerender the component. When the render eventually happens, a new local variable will be created with the new value, but code from your old render has no access to that.

If you need to run some code after calling setEnteredUsername, but you don't actually care if the component has rerendered yet, the just use the value in event.target.value, since you know that's going to be the new value of the state:

const usernameChangeHandler = (event) => {
  setEnteredUsername(event.target.value);
  console.log(event.target.value, enteredAge);
}

If instead you need to make make sure that the component has rerendered and then do something after that, you can put your code in a useEffect. Effects run after rendering, and you can use the dependency array to make it only run if the values you care about have changed:

const [enteredUsername, setEnteredUsername] = useState('');

useEffect(() => {
  console.log('rendering complete, with new username', enteredUsername);
}, [enteredUsername]);

const usernameChangeHandler = (event) => {
   setEnteredUsername(event.target.value);
};

CodePudding user response:

the act of setting state is asynchronous; therefore, console logging directly after setting your state will not accurately provide you with how state currently looks. Instead as many have suggested you can utilize the useEffect lifecycle hook to listen for changes in your enteredUserName state like so:

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

listening for changes within the useEffect will allow you to create side effects once state has updated and caused your component to rerender. This in turn will trigger your useEffect with the enteredUsername dependency, as the enteredUserName state has changed.

  • Related