Marcinek
Marcinek

Reputation: 47

React useState is not fresh in useEffect

My useState state is not up to date in useEffect function. It consoles log my old state after I changed it by setState inside useEffect. I know I can use useRef and pass it to useState but it doesn't work inside e.g. setTimeout. Example here (look at hook.js file and console.logs): https://codesandbox.io/s/prod-wildflower-qbwxt

import React, { useEffect, useState } from "react";
import "./styles.css";
import useLoading from "./hook";

function App() {
//  proptype isLoading simulation
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
 setTimeout(() => setIsLoading(true), 3000);
}, []);

// hook
const delayedLoading = useLoading(isLoading);

return (
 <div className="App">
   <h1>Hello {`${delayedLoading}`}</h1>
   <h2>Start editing to see some magic happen!</h2>
 </div>
);
}

export default App;
import React, { useEffect, useState } from "react";
import "./styles.css";
import useLoading from "./hook";

function App() {
  //  proptype isLoading simulation
  const [isLoading, setIsLoading] = useState(false);
  useEffect(() => {
    setTimeout(() => setIsLoading(true), 3000);
  }, []);

  // hook
  const delayedLoading = useLoading(isLoading);

  return (
    <div className="App">
      <h1>Hello {`${delayedLoading}`}</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

export default App;

Upvotes: 0

Views: 295

Answers (1)

Rohan Agarwal
Rohan Agarwal

Reputation: 2609

State updates are async in nature. It means that if you set a new value to your state using the setter method, it's not guaranteed that you will be able to get the new value by using the state in the next lines.

React combines all the setter method executions and executes it at once.

To solve your issue, you can store the value in a variable, update the value in the setter method, but continue with the value in the variable for rest of your execution

Upvotes: 0

Related Questions