skip to Main Content

i tried the code i attached, and for some reason when i log it the state remains at 5.
i got it working by adding a counter ref but im sure its supposed to work even without it.
pleasse help.

import React , {useEffect, useRef, useState} from 'react';
import styles from "./QuizTimer.module.css";

export default function QuizTimer(props)
{
  const timer = useRef();
  const [timeRemaining,setTimeRemaining] = useState(5);

  const handleTimeRemaining = () => {
    console.log(timeRemaining);
    if(timeRemaining ===1)
    {
      setTimeRemaining(5);
    }
    else{
      setTimeRemaining((prev) => {return prev-1;});
    }

  };

  useEffect(() => {
    timer.current = setInterval(handleTimeRemaining,1000);
  },[]);


  return (
    <div className={styles.container}>
        <h1 >{timeRemaining}</h1>
        <p>seconds</p>
    </div>
  );
}

3

Answers


  1. I think you are looking for something like this

    const [time, setTime] = useState(5)
    
    useEffect(() => {
        const timer = setInterval(() => {
            setTime((prev) => prev === 1 ? 5 : prev - 1)
            console.log(time)
        }, 1000)
        return () => clearInterval(timer)
    }, [time])

    But remember, that you will get a previous value of timer, so you need to log it like this

    console.log(time === 1 ? 5 : time - 1)
    Login or Signup to reply.
  2. setInterval is not precise, consider using the Date object instead see this example:

    import { useState, useEffect } from 'react';
    
    export function App() {
      const now = new Date();
      const countBackFrom = 5;
      
      const [date, setDate] = useState(now);
      const [expirationDate, setExpirationDate] = useState(new Date(now.setSeconds(now.getSeconds() + countBackFrom)));
      
      useEffect(() => {
        const intervalId = setInterval(() => {
          setDate(new Date());
        }, 1000)
    
        return () => clearInterval(intervalId);
      }, [])
    
      useEffect(()=> {
          if (date >= expirationDate) {
            const now = new Date();
    
            setExpirationDate(
              new Date(new Date(now.setSeconds(now.getSeconds() + countBackFrom)))
            );
          }
      }, [date, expirationDate]);
    
      return (
        <p className='clock'>
          {date.toLocaleTimeString()}
          {expirationDate.toLocaleTimeString()}
        </p>
      );
    }
    
    Login or Signup to reply.
  3. The handleTimeRemaining function was defined when timeRemaining = 5, and it will always remain at timeRemaining = 5 during execution.
    That is the reason.
    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search