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

88
Views
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 answers
Answer question

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 Report

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 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!