调用 clearTimeout 后触发的 React-Native setTimeout 函数
React-Native setTimeout function triggered after clearTimeout is called
在我的 react-native 应用程序中,我正在构建一个组件,该组件具有 'heads up display' 和一些控件,只有在触摸视图后才会出现。然后,在用户最后一次交互后的一秒钟,我希望这些按钮再次消失,以便看起来更干净。
我正在为此使用 setTimeout。每当用户与我的组件交互时,我都会触发一个函数。在这个函数中,我设置了一个超时时间为1秒,然后在触发时清除导航按钮。我还检查是否已经设置了另一个计时器(我将它们存储在状态中),然后取消它,因为我想确保只触发最新的超时功能。
这是代码:
const [timer, setTimer] = useState<number>(null)
const handleControlsInteraction = useCallback(() => {
// If the user interacted with the controls, we need to make them disappear 1 second after the latest interaction
// If a timer was already set by a previous interaction, we want to cancel it,
// because because the controls should disappear 1 second after the latest interaction
if (timer != null) {
console.log('Cancelling timeout: ', timer)
clearTimeout(timer)
}
// now we set a new timer for 1 second
let timeout = setTimeout(() => {
// When the function of the timer triggers, we need to hide the controls, clear the timeout and remove the timout from our local state
console.log('Hiding buttons for timeout: ', timeout)
setDisplayButtons(false)
clearTimeout(timer)
setTimer(null)
}, 1000);
console.log('Setting new timeout: ', timeout)
setTimer(timeout)
}, [timer])
当我 运行 这样做时,我点击我的控件两次(相隔半秒),我注意到我的第一个计时器按预期被取消了,但它的功能在那之后仍然被触发。这会导致我的控件在用户仍在与它们交互时隐藏,而不是在最近一次交互后 1 秒隐藏。
我想要实现的目标似乎是一件非常基本的事情。但是,我一直对此感到困惑。
我该如何解决这个问题?任何指导将不胜感激。
当您的组件更改状态并重新呈现时,新的 timeout
实例会重新创建并导致意外行为。
解决方案是跟踪每个组件重新呈现周期的原始超时实例。
React 为每个组件渲染周期提供 useRef
钩子以持久化值。
let timerRef = React.useRef(null);
useEffect(() => {
// Clear the interval when the component unmounts
return () => clearTimeout(timerRef.current);
}, []);
const handleControlsInteraction = () => {
if (timerRef.current != null) {
clearTimout(timerRef.current)
}
// now we set a new timer for 1 second
timerRef.current = setTimeout(() => {
setDisplayButtons(false);
}, 1000);
};
在我的 react-native 应用程序中,我正在构建一个组件,该组件具有 'heads up display' 和一些控件,只有在触摸视图后才会出现。然后,在用户最后一次交互后的一秒钟,我希望这些按钮再次消失,以便看起来更干净。
我正在为此使用 setTimeout。每当用户与我的组件交互时,我都会触发一个函数。在这个函数中,我设置了一个超时时间为1秒,然后在触发时清除导航按钮。我还检查是否已经设置了另一个计时器(我将它们存储在状态中),然后取消它,因为我想确保只触发最新的超时功能。
这是代码:
const [timer, setTimer] = useState<number>(null)
const handleControlsInteraction = useCallback(() => {
// If the user interacted with the controls, we need to make them disappear 1 second after the latest interaction
// If a timer was already set by a previous interaction, we want to cancel it,
// because because the controls should disappear 1 second after the latest interaction
if (timer != null) {
console.log('Cancelling timeout: ', timer)
clearTimeout(timer)
}
// now we set a new timer for 1 second
let timeout = setTimeout(() => {
// When the function of the timer triggers, we need to hide the controls, clear the timeout and remove the timout from our local state
console.log('Hiding buttons for timeout: ', timeout)
setDisplayButtons(false)
clearTimeout(timer)
setTimer(null)
}, 1000);
console.log('Setting new timeout: ', timeout)
setTimer(timeout)
}, [timer])
当我 运行 这样做时,我点击我的控件两次(相隔半秒),我注意到我的第一个计时器按预期被取消了,但它的功能在那之后仍然被触发。这会导致我的控件在用户仍在与它们交互时隐藏,而不是在最近一次交互后 1 秒隐藏。
我想要实现的目标似乎是一件非常基本的事情。但是,我一直对此感到困惑。
我该如何解决这个问题?任何指导将不胜感激。
当您的组件更改状态并重新呈现时,新的 timeout
实例会重新创建并导致意外行为。
解决方案是跟踪每个组件重新呈现周期的原始超时实例。
React 为每个组件渲染周期提供 useRef
钩子以持久化值。
let timerRef = React.useRef(null);
useEffect(() => {
// Clear the interval when the component unmounts
return () => clearTimeout(timerRef.current);
}, []);
const handleControlsInteraction = () => {
if (timerRef.current != null) {
clearTimout(timerRef.current)
}
// now we set a new timer for 1 second
timerRef.current = setTimeout(() => {
setDisplayButtons(false);
}, 1000);
};