amrlabib / react-timer-hook Goto Github PK
View Code? Open in Web Editor NEWReact timer hook
Home Page: https://www.npmjs.com/package/react-timer-hook
License: MIT License
React timer hook
Home Page: https://www.npmjs.com/package/react-timer-hook
License: MIT License
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.
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
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
.
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?
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!
When I click the start button multiple times after pausing, it always starts timing from the last paused 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?
I want a timer just with seconds ex: 90s. dont convert it to minutes after 60s
Hi, is there any possibility to stop the timer from outside of the timer component and then to get to the duration when the stop was performed? Thanks a lot.
On logging the values, they are the same as received initially in the component.
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?
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?
Please see the issue here:
https://codesandbox.io/s/react-timer-testing-3g6tg?file=/src/App.js
What I did wrong? It just seems not working
Is there a way to wait for it to start until I call the start() function or does it always automatically start on initialization?
expiryTimestamp is set to a number in your typescript definition, so we can no longer pass a date to it.
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:
I suggest an isPaused
flag like. Currently I need to hold a state besides the timer hook to realize play/pause button.
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.
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!
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.
Hello i'm benniger with react hooks but i want to get the timestamp for useStopwatch({}) when button pause clicked how can i do that please?
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>
)
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 lags when the counter is runnings
For testing i followed the below process:
I tried this a few more times and the useStopwatch always lagged behind other timers.
I am looking to add sound and also intervals in the timer.
Is this possible?
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
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!
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?
Hello! What do you think about rewriting code from JavaScript to TypeScript?
I could probably help with PR.
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
For example, setting the totalSeconds
to a certain numberr, and having the hours, minutes, seconds, etc. automatically set and then continue to count as normal from that point.
Hi,
It may be something that I do wrong, but if I assign onExpire
prop to an async function that handles an API request and receives a response containing a new timestamp that will be passed to the restart
function, when the timer expires, the function in called multiple times.
here is a sandbox example https://codesandbox.io/s/cool-wildflower-9v3ft?file=/src/App.js
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 like CodeSandbox to demonstrate the examples in the documentation for a more practical example?
If accepted, can this be assigned to me?
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!
Version: [email protected]
Browser: Safari iOS9.3
Problem: Safari does not fully support const
from react-timer-hook/dist/index.js
.
Please make a build for ES5 browsers?
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?
I've implemented this in next.js project. Timer is running properly. But I want when I submit any form then how to get the current time of the timer?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.