【发布时间】:2021-11-02 14:48:12
【问题描述】:
React 开发者您好。
所以我正在为客户编写一个应用程序。客户想要一个在视口中显示视频时播放视频(无声音,内联播放)的页面,并在视频超出视口时暂停。所以我做了一个自定义钩子来做到这一点。这是我的代码(忽略导入,只是 useRef 和 useEffect):
const usePlayVideo = options => {
const wrapperRef = useRef(null);
const videoRef = useRef(null);
const handleVid = entries => {
const [entry] = entries;
if (entry.isIntersecting) videoRef.current.play();
else videoRef.current.pause();
};
useEffect(() => {
const wrapper = wrapperRef.current;
const observer = new IntersectionObserver(handleVid, options);
if (wrapper) observer.observe(wrapper);
return () => {
if (wrapper) observer.unobserve(wrapper);
};
}, [wrapperRef, options]);
return [wrapperRef, videoRef];
};
export { usePlayVideo };
然后,在组件中,我导入钩子并像这样使用它:
function ClientAsk() {
const [wrapperRef, videoRef] = usePlayVideo({
root: null,
rootMargin: "0px",
threshold: 0.3,
})
return (
{/* bunch of other divs and stuff */}
<div className="grid_s_start_3 grid_s_span_20" ref={wrapperRef}>
<video ref={videoRef} id="video" playsInline muted preload="auto" loop style={{ width: "100%" }}>
<source src={ClientVid} type="video/mp4" />
</video>
</div>
{/* rest of other divs and stuff */}
);
}
export default ClientAsk;
就是这样。
在我的开发环境的浏览器中,这很好用!按预期工作!我很兴奋。
但我在我的 iPhone 上使用 iOS Safari 进行了尝试,它也可以工作...直到我在播放视频时返回上一页。
所以,页面顶部有一个“
但是,如果我停止滚动视频,并且它正在播放,并且我按下后退按钮(或 Safari 浏览器的后退按钮),我会收到一个开发错误:
TypeError: null is not an object (evaluating 'videoRef.current.pause')
handleVid
src/hooks/usePlayVideo.js:8
5 | const videoRef = useRef(null);
6 | const handleVid = entries => {
7 | const [entry] = entries;
> 8 | if (entry.isIntersecting) videoRef.current.play();
| ^ 9 | else videoRef.current.pause();
10 | };
现在,我想我知道为什么会发生这种情况......但是,我根本无法弄清楚如何解决这个问题或让错误停止发生。我想知道是否有人对此有任何提示?我在自定义钩子中使用了错误的钩子吗?我不应该使用“null”作为 useRef 的默认值吗?这只是一个 iOS 问题吗?
任何帮助将不胜感激。
谢谢!
【问题讨论】:
-
尝试改变这一行:
videoRef.current.play();到videoRef && videoRef.current.play();--- 还有:else videoRef && videoRef.current.pause(); -
@SajibKhan 我刚试过。不幸的是,它没有修复它。移动 iOS Safari 上的相同类型错误。 (在桌面上运行良好。)感谢您的回复!
-
VideoRef 总是真实的,它的
current值可能是假的(在这种情况下为空),你可以用if (videoRef.current) { }包装你的useEffect 逻辑或handleVid 逻辑 -
@Zac 澄清您的评论,您是说我应该用
if (videoRef.current)替换if (entry.isisIntersecting)吗?或将 videoRef.current 添加到当前条件?感谢您的回复! -
它与
entry.isisIntersecting条件无关,问题是在这种情况下你的代码是用videoRef.current=null执行的,在你当前的条件下,你要么调用.play()或.pause()两者都会产生相同的错误,因此您可以将这三行包含在handleVid函数中,条件为if (videoRef.current) { }
标签: javascript reactjs react-hooks null typeerror