Giter Site home page Giter Site logo

amrlabib / react-timer-hook Goto Github PK

View Code? Open in Web Editor NEW
492.0 4.0 108.0 2.42 MB

React timer hook

Home Page: https://www.npmjs.com/package/react-timer-hook

License: MIT License

JavaScript 100.00%
react react-hooks timer countdown timers component hook react-native javascript stopwatch

react-timer-hook's Issues

useStopwatch and useTime args are required

The arguments of useStopwatch and useTime are not optional, so it doesn't match the typescript definition. I would just make the arguments in index.d.ts not optional so it is clear that they are required.

Memoized callbacks from hooks

Hi!

Functions that return from the hook must be memoized because they can be used in effects, and the linter will require you to specify them depending. Now I had to memoize the functions myself, so as not to disable the linter. But after updating the linter, I still had to turn it off. Time to raise the problem.

Simple example (broken code):

    const {
        seconds,
        minutes,
        pause,
        restart,
    } = useTimer({
        expiryTimestamp: Date.now() + RE_SEND_AFTER_SECONDS * 1000,
        onExpire: () => setIsCanReSendSms(true),
    });

    useEffect(
        () => {
            if (screen === 'phoneConfirm') {
                restart(Date.now() + (RE_SEND_AFTER_SECONDS * 1000));
            } else {
                pause();
            }
        },
        [screen, pauseMemoized, restartMemoized],
    );

This will restart the effect with each renderer, because the functions are not memoized. Correct behavior - restarting the effect only when the variable "screen" is changed.

This can be added by removing callbacks from the dependencies. But this will force the developer to disable the linter, which is a bad decision in 99.9%.

Another solution is to add memoization yourself, but this is impractical and is now the reason for a new linter error. Now it looks like this.

    const {
        seconds,
        minutes,
        pause,
        restart,
    } = useTimer({
        expiryTimestamp: Date.now() + RE_SEND_AFTER_SECONDS * 1000,
        onExpire: () => setIsCanReSendSms(true),
    });

    // eslint-disable-next-line react-hooks/exhaustive-deps
    const pauseMemoized = useCallback(pause, []);
    // eslint-disable-next-line react-hooks/exhaustive-deps
    const restartMemoized = useCallback(restart, []);

    useEffect(
        () => {
            if (screen === 'phoneConfirm') {
                restartMemoized(Date.now() + (RE_SEND_AFTER_SECONDS * 1000));
            } else {
                pauseMemoized();
            }
        },
        [screen, pauseMemoized, restartMemoized],
    );

I think the problem needs to be solved radically. That is, in the source.

I was solving a similar problem nearby: pbeshai/use-query-params#46

Widen react-dom peer dependency version requirement

Thanks for making this! When installing this module, we get a warning about an unmet peer dependency on react-dom, as it looks like this module is set to require the exact version of 16.8.0. It seems like this module though works fine with newer versions of react-dom, and I wonder if it should be adjusted to be ^16.8.0 like the react peer depdendency? For reference, react-dom 16.8.0 was released in 02/2019, and they are currently up to 16.13.1.

useStopwatch hook is causing continuous rerender

Hi! I'm using this library for making user session time out. For that, I'm using useStopwatch hook.

const { hours, pause, reset } = useStopwatch({ autoStart: true });

But these causes render to the application every second. Is there a better way to achieve it or I'm implementing it wrong?

Ability to run the timer in smaller intervals (500ms)

Hi,

I had a use case where I needed to run a timer in 1.5 seconds and saw that it was running every second because of
the setInterval that is set to run each 1000ms.

I was wondering whether there is a reason not to support that?
I could work on adding that myself.

Thanks!

Start stopwatch from a given time

I need to start the stopwatch from a given time instead of 0.

example: initial start time is given as 5 minutes, then the stopwatch should start counting up from 5 minutes like 5:01, 5:02, 5:03

How can I achieve this functionality?

react native install issues

react-timer-hook lists react-dom as a peer dependency, and npm v7 installs peer dependencies by default. This makes clean react-native installs impossible, despite the tag on this repository.

Is react-dom a necessary dependency?

Is react-native supported?

Just a question

Does the timer sync across multiple tabs?
My use case is that, in my react app there is a timer which user will set and may leave or close the tab after hitting run button.
My question is will it sync if the user opens up another tab while the timer is running or will it start a new timer?

Timer automatically starts

Is there a way to wait for it to start until I call the start() function or does it always automatically start on initialization?

Not working with SSR

I'm trying to use this with Gatsby.js, but the problem is the UMD wrapper that is generated in the dist folder is referencing window, which breaks the build because window is not defined during SSR.

The best way to fix this/increase compatibility would be to generate builds for multiple targets (see https://medium.com/@kelin2025/so-you-wanna-use-es6-modules-714f48b3a953).

Another, quicker approach might be to include the src/ files in the npm package and reference the src/index.js via the "module" property in package.json

see also:

isPaused Flag

I suggest an isPaused flag like. Currently I need to hold a state besides the timer hook to realize play/pause button.

Unnecessary re-rendering

For some inexplicable reason, just using the hook to start a timer causes the component in question to re-render once per second. If you use the hook in a more complex component, it becomes a huge problem. At first I thought it might have been because of including the isRunning property from the returned object, but in fact, you don't have to use any of them, and your component will re-render regardless.

The following code snippet exhibits the behavior:

let counter = 0;
const HiddenTimer = props => {
    const {
        expiryTimestamp
    } = props;
    console.log("Will expire at " + expiryTimestamp);
    useTimer({expiryTimestamp, onExpire: () => console.log("Timer has expired"), autoStart: true});
    console.log("Timer is being rendered");

    return (
        <div>Counter at {counter++}</div>
    );
};

Add it to a simple app and you can observe that it is constantly being needlessly re-rendered.

Handling multiple timers

Hello,
First of all thanks a lot for the lib and your continuous work on it


It would be highly valuable for my project to be able to handle a dynamic number of timers (dynamicity making it incompatible with calling useTimer n-times)

The API could look like this:

export function useMultipleTimers(settings: TimerSettings): TimerResult

interface TimerSettings {
    // no expiryTimestamp: it MUST be defined at runtime (start or restart), making start & restart identical functions
    onExpire?: (timerId) => void;
}

interface TimerResult {
    getRemainingTime: (timerId: string) => {
        seconds: number;
        minutes: number;
        hours: number;
        days: number;
    };

    getIsRunning: (timerId: string) => boolean;
    start: (timerId: string, newExpiryTimestamp: Date, autoStart?: boolean) => void;
    pause: (timerId: string) => void;
    resume: (timerId: string) => void;
}

I could give it a go implementing it, but I am looking forward for your opinion beforehand ;)

Thanks!

Handle phones going sleep and tabs in the background

It seems this hook sets the initial time then counts down by second.

   if(isValidExpiryTimestamp(expiryTimestamp) && !intervalRef.current) {
      calculateExpiryDate();
      intervalRef.current = setInterval(() => subtractSecond(), 1000);
    }

But if the phone is asleep of course it can't count down. This means that when it wakes up, the count is behind. The fix could be something like subtracting from the end on each interval rather than depending on the current state.

restart Function not working as Expected

If I call restart after the timer has already expired, the timer updates to the new Date but it doesn't start counting down.

Simple Example:

const [hasTimeExpired, setHasTimeExpired] = useState(false);

let dt = new Date();

const {
    seconds,
    minutes,
    hours,
    days,
    isRunning,
    start,
    pause,
    resume,
    restart,
} = useTimer({ expiryTimestamp: dt, onExpire: () => setHasTimeExpired(true), autoStart: false });

useEffect(() => {
    let dt = new Date();

    dt.setSeconds(dt.getSeconds() + 15);

    restart(dt, true);
}, [])

useEffect(() => {
    let dt = new Date();
    dt.setSeconds(dt.getSeconds() + 120);

    restart(dt, true);
}, [hasTimeExpired])

return (
    <div className= "Clock-Wrapper">
        <span className="Clock-Time-Front">
            {hours}:{minutes}:{seconds}
        </span>
    </div>
)

how to dynamically change offsetTimestamp in useStopwatch

I want to change the offsetTimestamp dynamically to start from speicied value, but once the useStopwatch initialize, it doesn't take updated offsetTimestamp


export default function App() {
  const stopwatchOffset = new Date(); 
  const nn = stopwatchOffset.setSeconds(stopwatchOffset.getSeconds() + 300);
  const [timeDuration, setTimeDuration] = useState<number>(nn);
  return (
    <HeaderTimerHandler timeDuration={timeDuration} setTimeDuration={setTimeDuration} />
  );
}


const HeaderTimerHandler: React.FC<HeaderTimerHandlerProps> = (props) => {
  const { start, hours, minutes, seconds } = useStopwatch({ autoStart: false, offsetTimestamp: props.timeDuration });
  const hidePopover = () => {
    setVisiblity(false);
  }
 return <>{hours:minutes:seconds}</>

useStopwatch not working

useStopwatch lags when the counter is runnings

For testing i followed the below process:

  • I started the useStopwatch in my app, and the regular stop watch on my phone, at the same time.
  • Then i stopped them at the same time.
  • The useStopwatch logged time was 27 minutes.
  • The regular stop watch on my phone's logged time was 1 hour.

I tried this a few more times and the useStopwatch always lagged behind other timers.

Please support returning miliseconds

Hi there,

I have run into a use case where i need the miliseconds value from the useTimer hook.

Is it possible to add this to the core library ? ( or i might take a jab at this myself )

Thanks :D

Count up from a given timestamp

Is there any way to count up from a timestamp, i.e useStopwatch with a start timestamp passed to start the count from, or useTimer with a timestamp in the past.

I have tried doing the following, but this immediately expires

const t = new Date();
  t.setSeconds(t.getSeconds() - 600);
  const { hours, minutes, seconds } = useTimer({
    t,
  });

If this isn't available no worries, just wondered if I am missing something obvious. Thanks!

timer not accurate in mobile

It seems if I lock my phone and get back to the browser, it slows down and after 5 minutes the timer has just counted 20 seconds. How can the timer can be current after the browser becomes active after it being minimized or phone screen locked?

TypeScript?

Hello! What do you think about rewriting code from JavaScript to TypeScript?
I could probably help with PR.

Update dependency to react v17

Hi, I have a problem when installing this library. it's looks like that this library do not support react v17 yet.

Could not resolve dependency:
npm ERR! peer react@"^16.8.0" from [email protected]
npm ERR! node_modules/react-timer-hook
npm ERR! react-timer-hook@"*" from the root project

useTimer pause issue.

useTimer : When we press the pause button and then press the start button after a few seconds of delay, the timer does not start from the paused time.

Live demo

Live demo like CodeSandbox to demonstrate the examples in the documentation for a more practical example?

If accepted, can this be assigned to me?

useStopwatch reset with offsetTimestamp always restarts at 0

Hello! I love the library, thanks so much for making it!

I'm having an issue where calling useStopwatch's reset method with an offsetTimestamp always restarts the hook at 0 (seconds, minutes, hours, days).

In my example onSeek is being called with decimal seconds, much like I am computing currentTime.

export const ExampleComponent = (props: Props): React.ReactElement => {
  const { seconds, minutes, hours, days, isRunning, start, pause, reset } = useStopwatch({
    autoStart: false,
    offsetTimestamp: 0,
  })

  const currentTime = seconds + minutes * 60 + hours * 60 * 60 + days * 60 * 60 * 24
  const setCurrentTime = (newValue: number) => {
    const preserveRunning = isRunning
    reset(newValue - currentTime, preserveRunning)
  }
 ...

  return (
      <Container
        playing={isRunning}
        onPlayingChange={(newPlayValue) => {
          if (newPlayValue) {
            start()
          } else {
            pause()
          }
        }}
        currentTime={currentTime}
        ...
        onSeek={(newValue) => {
          setCurrentTime(newValue)
        }}
      />
  )
}

Thanks in advance for your help!

Does this handle on focus window?

Will the timer run correctly in the background if the window is not focused for a long duration?

For eg, if the user keeps the timer tab running and returns to the tab after 1-2 hrs will the timer be consistent?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.