Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

127
Views
Waiting for react state to update in function component

How can I make sure that handleOpen only executes after all the states (nameError, emailError, messageError) have been updated? My problem is that since state doesn't update immediately, sometimes handleOpen executes when it shouldn't.

const handleSend = (e) => {
e.preventDefault();
if (name === "") {
  setNameError(true);
}
if (email === "") {
  setEmailError(true);
  setEmailErrorMessage("Please type your email!");
}
if (!email.includes("@")) {
  setEmailError(true);
  setEmailErrorMessage("Invalid email address");
}
if (message === "") {
  setMessageError(true);
}
if (!nameError && !emailError && !messageError) {
  handleOpen();
}

};

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

I see that you are struggling with JS Event Loop. React states will update after an event loop is finished. So you can't expect them to update immediately in your handler function.

However there are some other solutions like using setTimeout(..., 0) to cheat the event loop, which is not going to help you in this case.

Here you need to refactor the handler method to handle the error states in your function scope and set the final result to the error states.

const handleSend = (e) => {
  e.preventDefault();
  
  const errors = {
    name: '',
    email: '',
    message: '',
  };
  
  if (name === "") {
    errors.name = "Please enter your name";
  }

  if (email === "") {
    errors.email = "Please type your email!";
  }

  if (!email.includes("@")) {
    errors.email = "Invalid email address";
  }

  if (message === "") {
    errors.email = "Please enter a message";
  }

  setNameError(!!errors.name);
  setNameErrorMessage(errors.name);
  setEmailError(!!errors.email);
  setEmailErrorMessage(errors.email);
  setMessageError(!!errors.message);
  setMessageErrorMessage(errors.message);

  if (Object.values(errors).filter(Boolean).length === 0) {
     handleOpen();
  }
}

I strongly suggest refactoring the error handling process in your application. Your solution and the one I wrote here is not efficient at all.

Good Luck ;)

about 4 years ago · Juan Pablo Isaza Report

0

I would do a whole refactor on how you are handling the errors, but answering your question, you could do just this:

const handleSend = (e) => {
    e.preventDefault();

    const isNameEmpty = name === "";
    const isEmailEmpty = email === "";
    const isEmailAtMissing = !email.includes("@");
    const isMessageEmpty = message === "";

    setNameError(isNameEmpty);
    setEmailError(isEmailEmpty || isEmailAtMissing);
    setEmailErrorMessage(isEmailEmpty ? "Please type your email!" : "Invalid email address");
    setMessageError(isMessageEmpty);

    if ([isNameEmpty, emailError, emailError].some(value => !!value)) {
        handleOpen()
    }
}

If you save the "errors" in variables, then you make sure you are checking the last values you are using in the states.

about 4 years ago · Juan Pablo Isaza Report

0

You can use react's useRef hook, for its not reactive, i.e doesnt cause page rerender so that you're sure

if (!nameError && !emailError && !messageError) {
  handleOpen();
}

executes when the right in the order you wanted just as i'll show below

const setNameError = useRef(null);
const setEmailError = useRef({value : false, message : ''});
const setMessageError = useRef(null);
const handleSend = (e) => {
e.preventDefault();
if (name === "") {
  setNameError.current = true;
}
if (email === "") {
  setEmailError.current.value = true;
  setEmailError.current.message = "Please type your email!";
}
if (!email.includes("@")) {
  setEmailError.current.value = true;
  setEmailError.current.message = "Invalid email address";
}
if (message === "") {
  setMessageError.current = true;
}
if (!setNameError.current && !setRmailError.current && !setMessageError.current) {
  handleOpen();
}
};

i have used bad naming conversion so as to go with your example, but in real life you wont chose setNameError for a variable name as I've done but maybe you'll do nameError

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!