I have the following stopwatch implementation
import { useState, useEffect } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
function TimerComponent() {
const [isActive, setIsActive] = useState(false);
const [time, setTime] = useState(0);
useEffect(() => {
let interval = null;
if (isActive) {
interval = setInterval(() => {
setTime(time => time + 0.1);
}, 100);
} else {
clearInterval(interval);
}
return () => {
clearInterval(interval);
};
}, [isActive]);
const handleStart = () => {
setIsActive(true);
};
const handleReset = () => {
setIsActive(false);
setTime(0);
};
const roundedTime = time.toFixed(1);
return (
<View style={styles.outerContainer}>
<Button
title="Start"
onPress={handleStart}
/>
<Text style={styles.text}>{roundedTime}</Text>
<Button
title="Stop"
onPress={handleReset}
/>
</View>
);
}
export default TimerComponent;
on Android it works as expected, when I compare to another stopwatch it reaches 30 seconds at the same time, but when I test on iOS it takes around 5 seconds longer.
Don‘t use setTime(time => time + 0.1);
to calculate the passed time.
Rather use Date
:
const start = Date.now();
console.log('starting timer...');
// Expected output: "starting timer..."
setTimeout(() => {
const millis = Date.now() - start;
console.log(`seconds elapsed = ${Math.floor(millis / 1000)}`);
// Expected output: "seconds elapsed = 2"
}, 2000);