I have a server component which loads info about a user video, like so
const MyPage = async() => { const user: SessionUser = (await requireAuth(false)) as SessionUser; const currentVideo = await getCurrentLeadershipMinuteVideo(user.id); return (<div><Script src="https://www.youtube.com/iframe_api"></Script> {!currentVideo ? (<p>There is no Video available at this time</p> ) : (<VideoPlayer currentVideo={currentVideo} /> )}</div> );}
My client component renders the iframe using the link from the server component.
const VideoPlayer = (props: LeadershipMinuteVideoProps) => { const { currentVideo } = props; const link = currentVideo.link as string; const title = currentVideo.title as string; const iframeRef = useRef<HTMLIFrameElement | null>(null); const playerRef = useRef<any>(null); const [isPlaying, setIsPlaying] = useState<boolean>(false); const pauseVideo = () => { playerRef.current.pauseVideo(); }; const playVideo = (): boolean => { // returns false if I remove destroy() function if (playerRef.current && playerRef.current.playVideo) { playerRef.current.playVideo(); return true; } return false; }; const onPlayerStateChange = (event: any) => { if (event.data === window.YT.PlayerState.PLAYING) { //... } }; useEffect(() => { const onYouTubeIframeAPIReady = () => { if (iframeRef.current) { playerRef.current = new window.YT.Player(iframeRef.current, { events: { onStateChange: onPlayerStateChange, }, }); } }; if (window.YT && window.YT.Player) { onYouTubeIframeAPIReady(); } else { window.onYouTubeIframeAPIReady = onYouTubeIframeAPIReady; } return () => { if (playerRef.current) { playerRef.current.destroy(); // keep ? } }; }, [playerRef]); return (<><iframe ref={iframeRef} width="884" height="497" src={link +'?enablejsapi=1&controls=0&disablekb=1&autoplay=0'} title={title} style={{ pointerEvents: 'none' }} frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerPolicy="strict-origin-when-cross-origin" allowFullScreen></iframe> {!isPlaying && (<Button type="button" onClick={() => { const didPlay = playVideo(); if (didPlay) setIsPlaying(true); }}> Play</Button> )}</> );};
The issue is that when I navigate away from this page (using Link from 'next/link') and come back to it, the iframe is destroyed. I understand I am destroying it in my useEffect cleanup, but do not understand why it is not re-instantiated when I navigate back to the page. Can someone explain why this happens?
When I comment out the playerRef.current.destroy()
the iframe re-appears, but the fuctions associated with the YT player do not exist, i.e. "Uncaught TypeError: playerRef.current.playVideo is not a function". Any help would be appreciated