我正在尝试查看视频是否已加载并可以在子组件(LandingComponent)中播放,如果已加载,我希望父组件(App)将load设置为true并删除微调器(SpinnerComponent)并显示整个网页。
我总是在父组件中的“video”上得到一个null。即使给予它是否不为null,微调器也会继续无限旋转。进一步检查时,我发现着陆组件也没有得到渲染
import React, { useEffect, useState } from "react";
import NavbarComponent from './Components/Navbar/navbar';
import AboutComponent from './Components/About/about';
import HealthComponent from './Components/Health/health';
import SpinnerComponent from './Components/Spinner/spinner';
import LandingComponent from './Components/Landing/landing';
import ContactUs from './Components/ContactUs/contactUs';
import Footer from './Components/Footer/footer';
function App() {
const [loaded, setLoaded] = useState(false);
useEffect(() => {
const video = document.getElementById('landing-video');
console.log('video element:', video); // This is always null
if (video) {
video.addEventListener('canplaythrough', () => {
setLoaded(true);
});
}
}, []);
return (
<>
{loaded ? (
<>
<NavbarComponent/>
<LandingComponent onLoad={() => setLoaded(true)}/>
<AboutComponent/>
<HealthComponent/>
<ContactUs/>
<Footer/>
</>
) : (
<SpinnerComponent fullscreen={true} />
)}
</>
);
}
export default App;
Landing.js
import React, {useEffect, useLayoutEffect, useRef, useState} from 'react'
import './styleLanding.css';
import AOS from 'aos';
import 'aos/dist/aos.css';
import sample from '../../videos/movie.mp4'
export const LandingComponent = () => {
console.log('LandingComponent rendered'); // This is also null
const [loaded, setLoaded] = useState(false);
const videoRef = useRef(null);
useEffect(() => {
AOS.init();
const video = videoRef.current;
if (video) {
video.addEventListener('canplaythrough', () => {
video.play();
setLoaded(true);
});
}
}, []);
return (
<div id="home" className="style-landing" >
<div className="style-overlay"></div>
<video ref={videoRef} id="landing-video" src={sample} type={'video/mp4'} preload={'auto'} className="style-video" autoPlay loop muted/>
<div className="style-content">
<h2 className="style-heading" data-aos="zoom-in" data-aos-duration="1000" data-aos-offset="130">EXPERIENCE THE BEST</h2>
<h1 className="style-sub-heading" data-aos="zoom-in" data-aos-duration="1000" data-aos-offset="130">nutrition</h1>
</div>
</div>
)
}
export default LandingComponent
1条答案
按热度按时间lymnna711#
这里只需要做一些调整。首先,如果我在App.js中解决这个问题,
LandingComponent包含在condition中。如果“loaded”状态为真,则只有在此情况下,才会将组件及其html添加(插入)到DOM中。
**因为,“loaded”状态最初是假的,视频标记甚至没有插入DOM中。**所以你不能用任何方法捕获元素。你不能通过document.getElementById得到它...所以你的微调器无限显示。
解决方法---
将微调器显示为覆盖层。这样,视频标签将被添加到DOM中,您可以添加侦听器并执行操作。
作为示例,请尝试以下代码以了解...
在您的代码中,一旦video标签被添加到DOM中,您就可以使用原始代码在子组件中访问它。
主要的问题是LandingComponent一开始就没有出现在DOM中。