Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React hooks setState not updating immediately

I am trying to validate field when I click on submit button. This is how I defined my state.

  const [values, setValues] = useState({
    email: "",
    password: "",
    emailErrorMessage: "",
    passwordErrorMessage: "",
    errorMessage: "",
    emailError: false,
    passwordError: false,
    rememberMe: false,
  });

In submit method, this is how I am validating it.

if (values.email.length <= 0) {

  setValues({
    ...values,
    emailError: true,
    emailErrorMessage: "Email field must not be empty"
  })
};

if (values.password.length <= 0) {
  setValues({ ...values, passwordError: true, passwordErrorMessage: "Password field must not be empty" });
}

For somehow it is only showing me error for password field. Although it is going through both the if conditions. Not sure how exactly I can Fix it.

Expected:- it should show error for both email and password.

like image 358
Garry Avatar asked Jun 08 '19 21:06

Garry


People also ask

Why React setState setState does not update immediately?

State updates in React are asynchronous; when an update is requested, there is no guarantee that the updates will be made immediately. The updater functions enqueue changes to the component state, but React may delay the changes, updating several components in a single pass.

Does useState hook update immediately?

PureComponent , the state update using the updater provided by useState hook is also asynchronous, and will not be reflected immediately.

Why isn't my state updating React?

The reason why the state doesn't update immediately is because for each render, the state is immutable. …are both constants values ! So they're immutable. The state remains constant inside the render but can be changed between two renders.

How wait for state to update React?

Use the useEffect hook to wait for state to update in React. You can add the state variables you want to track to the hook's dependencies array and the function you pass to useEffect will run every time the state variables change.


1 Answers

Problem 1: The state update is an asynchronous process, so, in your case, you're updating the state for the first time by spreading the current state, then you're updating it for the second time, by spreading also the current state (not updated yet). As a result, the last state successfully updated (it's a gamble actually, with more luck for the second update) will be the actual nextState, that's why you encounter the password being updated only

Problem 2: Every state update triggers a re-render. You're updating the state twice (even though it's done wrong, but it's a fact), when you could do it just once (to have just one re-render).

A solution to solve both problems will be:

const newValues = {...values};

if (values.email.length <= 0) {
  newValues.emailError = true;
  newValues.emailErrorMessage = "Email field must not be empty";
};

if (values.password.length <= 0) {
  newValues.passwordError = true;
  newValues.passwordErrorMessage = "Password field must not be empty";
}

setValues(newValues);
like image 148
Radu Nemerenco Avatar answered Oct 22 '22 11:10

Radu Nemerenco