I have a long process that updates the state. I want to show red background when it's running and blue when it's done.
const MapBuilder = (props) => {
    const [backgroundColor, setBackgroundColor] = useState(false);
    const [fancyResult, setFancyResult] = useState(null);
    console.log(`stop 1 backgroundColor ${backgroundColor} fancyResult ${fancyResult}`)
    const veryHardWork = () => {
         setBackgroundColor("red");
         console.log(`stop 2 backgroundColor ${backgroundColor} fancyResult ${fancyResult}`)
         for (let i = 0; i < 1000; i++) {
            for (let j = 0; j < 1000; j++) {
              console.log("So hard")
         }
    }
   setFancyResult("done")
   console.log(`stop 3 backgroundColor ${backgroundColor} fancyResult ${fancyResult}`)
   setBackgroundColor("blue") 
   console.log(`stop 4 backgroundColor ${backgroundColor} fancyResult ${fancyResult}`)
}
return (<div style={{background: backgroundColor}}>
   <button className="btn btn-primary" onClick={veryHardWork}></button>
</div>)
}
Here is an output of such run
stop 1 backgroundColor false fancyResult null
MapBuilder.js:13 stop 2 backgroundColor false fancyResult null
10000MapBuilder.js:16 So hard
MapBuilder.js:20 stop 3 backgroundColor false fancyResult null
MapBuilder.js:22 stop 4 backgroundColor false fancyResult null
MapBuilder.js:10 stop 1 backgroundColor blue fancyResult done
I understand from this that the state change only happens after the method veryHardWork  is finished. In my real project, I actually want to show a spinner the question is how can I do it if the state is only changed at the end of the method.
I think some clarification needs to be added. In reality, I allow the user to choose a file after the user chooses the file it is loaded and some heavy processing is performed on files data while the processing is running I want to show a spinner no Asyn work involved.
Some of the answers sugested to use useEffect and moving it to a promise I tryied both but it did not help here is a different take on it which also did not work
const MapBuilder = (props) => {
  const [backgroundColor, setBackgroundColor] = useState(false);
  const [fancyResult, setFancyResult] = useState(null);
  const [startProcessing, setStartProcessing] = useState(null);
  useEffect(() => {
    let myFunc = async () => {
      if (startProcessing) {
        setBackgroundColor("red");
        await hardWork();
        setBackgroundColor("blue");
        setStartProcessing(false);
      }
    }
    myFunc();
  }, [startProcessing])
  const hardWork =  () => {
    return new Promise((resolve)=> {
      for (let i = 0; i < 500; i++) {
        for (let j = 0; j < 100; j++) {
          console.log("So hard")
        }
      }
      setFancyResult("sdsadsad")
      resolve("dfsdfds")
    })
  }
  return (<div style={{background: backgroundColor}}>
    <button className="btn btn-primary" onClick={() => setStartProcessing(true)}></button>
  </div>)
}
export default MapBuilder;
 
     
     
     
    