react-idle-timer icon indicating copy to clipboard operation
react-idle-timer copied to clipboard

Issue when resetting timer🐞

Open leahyjulian opened this issue 2 years ago • 1 comments

What happened?

When resetting the timer it appears to reset correctly when tracking remaining time, however the timeout value doubles before onIdle is called again

Reproduction Steps

1. set a timeout for 10 seconds
2. increase a count var every time idle is called 
3. reset timer
4. After first 10 seconds counter increase by 1 as expected
5. next time counter does not increase again for 20 seconds
6. New timeout appears to have doubled

Relevant log output

No response

Screenshots or Additional Context

sandbox

import { useIdleTimer } from "react-idle-timer";
import { useEffect, useState } from "react";

export default function App() {
  const [remaining, setRemaining] = useState(0);
  const [count, setCount] = useState(0);

 // correct behaviour first time onIdle is called
 // after reset onIdle is called every 20 seconds instead of 10
  const onIdle = () => {
    setCount((prev) => (prev += 1));
    reset();
  };

  const { reset, getRemainingTime } = useIdleTimer({
    onIdle,
    timeout: 10_000,
    throttle: 500,
  });

  useEffect(() => {
    const interval = setInterval(() => {
      setRemaining(Math.ceil(getRemainingTime() / 1000));
    }, 500);

    return () => {
      clearInterval(interval);
    };
  });
  return (
    <div className="App">
      <h1>Reset</h1>
      <h2>Time Remaining {remaining}</h2>
      <h2>Count: {count}</h2>
    </div>
  );
}

Module Version

5.7.2

What browsers are you seeing the problem on? Select all that apply.

Chrome

What devices are you seeing the problem on?

Desktop

Verification

  • [X] I have checked for existing closed issues and discussions.

leahyjulian avatar Nov 30 '23 22:11 leahyjulian

Is this issue fixed? I have the latest version and calling start/reset sill doubles the timeout value. In my case, I'm reseting the timer in onIdle if some condition is false. When logging the getRemainingTime on a timer of 5s, it goes from 5 to 1, then if the start is called, the log goes again from 5 to 1 and instead of idling out, the log goes again from 5 to 1.

  const timer = useIdleTimer({
    onIdle: (event?: Event, idleTimer?: IIdleTimer) => {
      const lastActivityString = Cookies.get(LAST_ACTIVITY_TIME_COOKIE_NAME);
      const currentTime = Date.now();

      if (lastActivityString) {
        const lastActivity = Number.parseInt(lastActivityString, 10);
        if (currentTime - lastActivity >= userIdleTimeout) {
          // void logout(true); // isIdleSessionLogout = true
          console.log('Logout:', currentTime - lastActivity);
        } else {
          console.log('Reset:', currentTime - lastActivity);
          idleTimer?.start();
        }
      }
    },
    onAction: (event?: Event, idleTimer?: IIdleTimer) => {
      const lastActivity = idleTimer?.getLastActiveTime();
      if (lastActivity) {
        Cookies.set(
          LAST_ACTIVITY_TIME_COOKIE_NAME,
          lastActivity.getTime().toString(),
          { domain: cookieBaseUrl, sameSite: 'lax' }
        );
      }
      console.log('Action:', appName);
    },
    events: ['mousemove', 'keydown', 'visibilitychange'],
    timeout: userIdleTimeout,
    eventsThrottle: THROTTLE_TIME_MILLISECONDS,
    crossTab: true,
    name: appName,
    syncTimers: THROTTLE_TIME_MILLISECONDS,
  });

  useEffect(() => {
    const interval = setInterval(() => {
      console.log(Math.ceil(timer.getRemainingTime() / 1000));
    }, 500);

    return () => {
      clearInterval(interval);
    };
  });

reeson46 avatar Jan 25 '25 15:01 reeson46