如何计算本机反应中两个时刻之间的差异
How to calculate difference between two moments in react native
我正在尝试计算持续时间(两个时刻之间的差异),例如目前我正在处理一个本机反应项目,我必须计算在 screen/card 上花费的时间。
所以现在我正在尝试计算这样花费的时间:
import moment from 'moment';
// lets say i have 3 states to note time
const [startTime, setStartTime] = useState(moment());
const [endTime, setEndTime] = useState(moment());
const [elapsedTime, setElapsedTime] = useState(Number);
// assume i have a bottomSheet, so whenever that bottom sheet goes up the timer starts and when it goes down to original position, timer stops and calculate difference/duration in minutes.
// so for the onOpenStart on onCloseEnd props of the bottomsheet, this is my function:
const start = () => {
setStartTime(moment());
}
const end = () => {
setEndTime(moment());
const et = moment.duration(endTime.diff(startTime)).asSeconds();
setElapsedTime(et);
console.log(elapsedTime) // if i try for 10 seconds it logs 34, or sometimes -6, it's just not right
}
我尝试使用 new Date
方法,如果我尝试 10 秒,它会记录 34,有时是 -6,这是不对的,但无法成功...
任何帮助将不胜感激。
在您的特定情况下,我认为您甚至不需要 moment
库。捆绑包中的它非常重,根本不需要它。
您不需要用日期初始化状态。当组件刚刚挂载时,您不关心它们,对吗?您想跟踪函数 start
和 end
被触发的日期。
当前的行为是这样的,因为 useState
是异步的。这意味着您正在尝试设置状态,然后在下一行中使用此值进行一些计算 - 这是行不通的。
你可以做的是使用useRef
而不是useState
。这样您就可以确保您拥有的值是整个组件中最新的值。
const startTime = useRef(new Date());
const endTime = useRef(new Date());
const [elapsedTime, setElapsedTime] = useState();
const start = () => {
startTime.current = new Date();
}
const end = () => {
endTime.current = new Date();
const et = (startTime.current - endTime.current) / 1000 // get the seconds
setElapsedTime(et);
console.log(et); // You cannot log elapsedTime here, because again, useState is async
}
我不知道你需要用经过的时间做什么,你可能也不需要状态。现在我将其保留为状态。
最后一件事:我真的推荐查看 day.js 库,因为它与 moment 做同样的事情(在 99% 的情况下),但要轻得多。
useState 不同步更新。这意味着尽管您设置了 EndTime 然后尝试读取它,但它很可能尚未更新。
此外,设置状态会导致重新渲染。这在衡量性能时并不重要。您可以改为使用 useRef
将计时值保存在参考变量中。
export default function App() {
const [visible, setVisible] = React.useState(false);
const timer = React.useRef(null)
return (
<View style={styles.container}>
<Pressable
onPress={() => {
timer.current = new Date().getTime()
setVisible(true);
}}>
<Text>Show modal</Text>
</Pressable>
<Pressable
onPress={() => {
setVisible(false);
alert(new Date().getTime() - timer.current)
}}>
<Text>Hide modal</Text>
</Pressable>
{visible ? (
<Card>
<Text>Modal content</Text>
</Card>
) : null}
</View>
);
}
在这里,我们设置可见值并存储按下时的时间戳。当用户按下隐藏时,我们使用存储的时间来计算经过的时间。
我正在尝试计算持续时间(两个时刻之间的差异),例如目前我正在处理一个本机反应项目,我必须计算在 screen/card 上花费的时间。 所以现在我正在尝试计算这样花费的时间:
import moment from 'moment';
// lets say i have 3 states to note time
const [startTime, setStartTime] = useState(moment());
const [endTime, setEndTime] = useState(moment());
const [elapsedTime, setElapsedTime] = useState(Number);
// assume i have a bottomSheet, so whenever that bottom sheet goes up the timer starts and when it goes down to original position, timer stops and calculate difference/duration in minutes.
// so for the onOpenStart on onCloseEnd props of the bottomsheet, this is my function:
const start = () => {
setStartTime(moment());
}
const end = () => {
setEndTime(moment());
const et = moment.duration(endTime.diff(startTime)).asSeconds();
setElapsedTime(et);
console.log(elapsedTime) // if i try for 10 seconds it logs 34, or sometimes -6, it's just not right
}
我尝试使用 new Date
方法,如果我尝试 10 秒,它会记录 34,有时是 -6,这是不对的,但无法成功...
任何帮助将不胜感激。
在您的特定情况下,我认为您甚至不需要 moment
库。捆绑包中的它非常重,根本不需要它。
您不需要用日期初始化状态。当组件刚刚挂载时,您不关心它们,对吗?您想跟踪函数
start
和end
被触发的日期。当前的行为是这样的,因为
useState
是异步的。这意味着您正在尝试设置状态,然后在下一行中使用此值进行一些计算 - 这是行不通的。你可以做的是使用
useRef
而不是useState
。这样您就可以确保您拥有的值是整个组件中最新的值。const startTime = useRef(new Date()); const endTime = useRef(new Date()); const [elapsedTime, setElapsedTime] = useState(); const start = () => { startTime.current = new Date(); } const end = () => { endTime.current = new Date(); const et = (startTime.current - endTime.current) / 1000 // get the seconds setElapsedTime(et); console.log(et); // You cannot log elapsedTime here, because again, useState is async }
我不知道你需要用经过的时间做什么,你可能也不需要状态。现在我将其保留为状态。
最后一件事:我真的推荐查看 day.js 库,因为它与 moment 做同样的事情(在 99% 的情况下),但要轻得多。
useState 不同步更新。这意味着尽管您设置了 EndTime 然后尝试读取它,但它很可能尚未更新。
此外,设置状态会导致重新渲染。这在衡量性能时并不重要。您可以改为使用 useRef
将计时值保存在参考变量中。
export default function App() {
const [visible, setVisible] = React.useState(false);
const timer = React.useRef(null)
return (
<View style={styles.container}>
<Pressable
onPress={() => {
timer.current = new Date().getTime()
setVisible(true);
}}>
<Text>Show modal</Text>
</Pressable>
<Pressable
onPress={() => {
setVisible(false);
alert(new Date().getTime() - timer.current)
}}>
<Text>Hide modal</Text>
</Pressable>
{visible ? (
<Card>
<Text>Modal content</Text>
</Card>
) : null}
</View>
);
}
在这里,我们设置可见值并存储按下时的时间戳。当用户按下隐藏时,我们使用存储的时间来计算经过的时间。