我在函数组件中有以下钩子。
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
作为控制计时的选项。