如何安全地将 setTimout 与 refs 结合使用?



我在函数组件中有以下钩子。

useEffect(() => {
if (isMinimized) {
// When minimizing, delay swapping the element to the minimized node.
// This gives the video takeover minimize animation time to run and results
// in a more seamless looking video swap
if (videoMinimizedRef.current !== null) {
setTimeout(() => {
setOuterContainer(minimizedVideoRef.current);
}, VIDEO_OVERLAY_VIDEO_ELEMENT_SWAP_TIMEOUT);
}
} else {
// When maximizing, immediately swap the video element to the maximized
// node. This ensures the video element is present at the start of the animation.
if (videoMaximizedCallbackRef !== null) {
setOuterContainer(videoMaximizedCallbackRef);
}
}
}, [isMinimized, setOuterContainer, videoMinimizedRef, videoMaximizedCallbackRef]);

isMinimized, setOuterContainer, videoMinimizedRef都是传递给组件的道具。

  • isMinimized是一个布尔值
  • setOuterContainer是一个useState资源库函数,它接收HTMLElement并将其设置为正在播放的视频元素的新父节点。
  • videoMinimizedRef是最小化播放时视频容器的参考。

videoMaximizedCallbackRef是在此组件中设置的回调引用(没有.current(。

钩子按原样工作,完全按照我想要的方式工作。也就是说,我意识到这个钩子有一些问题(至少从阅读 React 钩子文档和常见问题解答来看似乎是这样(。例如,没有清理设置超时。可以这样添加:

useEffect(() => {
let timeout;
if (isMinimized) {
// When minimizing, delay swapping the element to the minimized node.
// This gives the video takeover minimize animation time to run and results
// in a more seamless looking video swap
if (videoMinimizedRef.current !== null) {
timeout = setTimeout(() => {
setOuterContainer(minimizedVideoRef.current);
}, VIDEO_OVERLAY_VIDEO_ELEMENT_SWAP_TIMEOUT);
}
} else {
// When maximizing, immediately swap the video element to the maximized
// node. This ensures the video element is present at the start of the maximize animation.
if (videoMaximizedCallbackRef !== null) {
setOuterContainer(videoMaximizedCallbackRef);
}
}
return () => clearTimeout(timeout);
}, [isMinimized, setOuterContainer, videoMinimizedRef, videoMaximizedCallbackRef]);

但是添加这将导致每次任何依赖项更改时清除超时。我需要确保超时在启动时永远不会被清除,因为它会导致视频交换在不完全之后发生

VIDEO_OVERLAY_VIDEO_ELEMENT_SWAP_TIMEOUT毫秒,但

VIDEO_OVERLAY_VIDEO_ELEMENT_SWAP_TIMEOUT + sum of time passed in previous cleared setTimeouts毫秒

我怎样才能以一种消除陈旧闭包和不需要的clearTimeout调用的陷阱的方式编写这个钩子?

我想遵守钩子和详尽依赖项的规则,但这对我来说有点太多了。

你做的方式会很好。设置间隔时,这不是正确的方法,但对于超时,它就像一个魅力。

useEffect(() => {
let timeout;
timeout = setTimeout(() => {
// set timeout callback, write your code here
}, 100)
return () => {
clearTimeout(timeout)
}
}, [yourDependencies])

您可以从丹·阿布拉莫夫的博客中阅读更多内容:https://overreacted.io/a-complete-guide-to-useeffect/

如果您有一个超时的事件,但您也可以清除该事件,则表明需要使用

间隔计时器设置一次,并在间隔处重复

tRef = setInterval(theFuncCall,timeMills)

并清除

clearInterval( tRef );

如果您正在查看 100 毫秒的呼叫间隔,那么您应该使用setInterval作为控制计时的选项。

相关内容

  • 没有找到相关文章

最新更新