Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

128
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda