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

96
Visualizações
Change state while waiting for loop to finish

OnClick I want to call a function that sets my loading state to true then do a for loop which will take more than one second and on the last loop set the loading state back to false but in my code the loading state doesn't change as expected. What do I have to fix?

import { useState } from "react"

const Test = () => {
  const [loading, setLoading] = useState(false)

  const someFunction = () => {
    setLoading(true)

    const someVeryBigArray = [...]
    for (let i = 0; i < someVeryBigArray.length; i++) {
      if (i === someVeryBigArray.length - 1) {
          setLoading(false)
      }
    }
  }

  return (
    <button onClick={someFunction} className={`${loading && "text-red-500"}`}>
      test
    </button>
  )
}

export default Test
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

You need to give the browser time to re-render. If you have a huge blocking loop, React won't be yielding control back to the browser so that it can repaint (or even to itself so that the component can run again with the new state).

While one approach would be to run the expensive function in an effect hook, after the new loading state has been rendered:

const Test = () => {
  const [running, setRunning] = useState(false)
  useEffect(() => {
    if (!running) return;
    const someVeryBigArray = [...]
    for (let i = 0; i < someVeryBigArray.length; i++) {
      // ...
    }
    setRunning(false);
  }, [running]);
  return (
    <button onClick={() => setRunning(true)} className={running && "text-red-500"}>
      test
    </button>
  )
}

A better approach would be to offload the expensive code to either the server, or to a web worker that runs on a separate thread, so as not to interfere with the UI view that React's presenting.

about 4 years ago · Juan Pablo Isaza Relatório

0

To be honest if in any case your loop is taking 1 second to run, then this will cost into you app's performance. And this is not the best way to do as well.

The better way would be, If your really want to replicate the delay in you app then you should use setTimeout() using which you delay some action. sharing a code snippet might help you.

JSX

import { useEffect, useState } from "react";
const Test = () => {
  const [loading, setLoading] = useState(false);
  let timevar = null;
  const someFunction = () => {
    setLoading(true);
    timevar = setTimeout(() => {
      setLoading(false); //this will run after 1 second
    }, 1000); //1000 ms = 1 second
  };
  useEffect(() => {
    return () => {
      //clear time out if in case component demounts during the 1 second
      clearTimeout(timevar);
    };
  });
  return (
    <button onClick={someFunction} className={`${loading && "text-red-500"}`}>
      test
    </button>
  );
};
export default Test;
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