Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading