skip to Main Content

Can you please tell me why my useState is still empty? It doesn’t want to update it. I am using setInteraval and function to update data and than want to set up useState by current time, but useState ignore setTimeOut(res) in formatTime.
Can you please show me how to fix it?

Edit: if I put number to useState

const [timeOut, setTimeOut] = useState(30)

it will be there just second and than is gone, I have empty field.
Seems setInterval deleted everything inside, so how to fix it?


const Timer = ({item}) => {

  const [timeOut, setTimeOut] = useState('')  // << doent want to update it from 
                                              //         formatTime function
  console.log(timeOut) // still empty


useEffect(() => {
    if (status !== 'unPaid') return;

    const timer = window.setInterval(() => {
        setTimeOut(formatTime(createdAt));
    }, 1000);

    return () => window.clearInterval(timer);
}, [createdAt, status]);



const formatTime = (time) => {
         console.log(time) //  2023-07-25T23:39:39.253Z

         // const timer = new Date(time).getTime() + 1800000
          const timer = new Date(time).getTime() + 250000
          let countDown = new Date().getTime()
          let distance = timer - countDown

          let min = Math.floor((distance % (1000*60*60) / (1000*60)))
          let sec = Math.floor((distance % (1000*60) / (1000)))
          let res = Math.abs(min) + ':' + Math.abs(sec)
          console.log(res)   //  4:50
          setTimeOut(res)   // <<<<<   it doesnt want to apdate my useState
           
 }

2

Answers


  1. This is most likely because you are setting the state inside a timeout.

    Another issue is that you are calling setTimeout inside itself.

    instead, use a function that returns a new value based on the previous state.

    useState accepts a function that receives the previousState as an argument

    const [count, setCount] = useState(0);
    
    useEffect(() => {
      window.setTimeout(() => {
        setCount((prevValue) => {
          return prevValue + 1; // what you return here, will be the new state.
        })
      }, 1000)
    }, []);
    
    
    Login or Signup to reply.
  2. Looks like the problem is that the setInterval is running every second, and it updates the state (timeOut) every second.

    Also in formatTime function, you are using the current time (new Date().getTime()) instead of the createdAt time. As a result, the state is updated continuously with a new value every second.

    here is the updated code.

    const Timer = ({ item }) => {
      const [timeOut, setTimeOut] = useState('');
    
      useEffect(() => {
        if (status !== 'unPaid') return;
    
        const timer = window.setInterval(() => {
          setTimeOut(formatTime(createdAt));
        }, 1000);
    
        return () => window.clearInterval(timer);
      }, [createdAt, status]);
    
      const formatTime = (time) => {
        const timer = new Date(time).getTime() + 250000;
        const currentTime = new Date().getTime();
        const distance = timer - currentTime;
    
        let min = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
        let sec = Math.floor((distance % (1000 * 60)) / 1000);
        let res = Math.abs(min) + ':' + Math.abs(sec).toString().padStart(2, '0');
        return res;
      };
    
      return <div>{timeOut}</div>;
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search