I'm learning React by converting a previous jQuery based web app, over to React. However I have hit a snag. I'm trying to get a hidden video to play after x seconds using react-simple-idle-monitor. The I can get the video frame to play, and if I add the controls attribute the video can be played but I work out how to access the video using react.
I have tried using refs, and accessing the document.getElementById('video').
This is my Screensaver component in Screensaver.js
import React, { Component } from 'react';
type Props = {};
export default class Screensaver extends Component<Props> {
props: Props;
render() {
return (
<div className="screensaver">
<video muted loop>
<source
src="../assets/video/my-video.mp4"
type="video/mp4"
/>
</video>
</div>
);
}
}
Here is my render function in App.js
render() {
return (
<IdleMonitor
activeClassName="appActive"
idleClassName="appIdle"
timeout={30000}
onActive={stopScreensaver}
onIdle={startScreensaver}
>
<div className="panels">
<Home />
<Screensaver />
</div>
</IdleMonitor>
);
}
And here are the functions to start and stop the screensaver in actions/screensaver.js
export function startScreensaver() {
const videoFile = document.getElementById('screensaver-video');
videoFile[0].play();
}
export function stopScreensaver() {
const videoFile = document.getElementById('screensaver-video');
videoFile[0].pause();
videoFile[0].currentTime = 0;
}
After the timeout triggers, the video container is shown via CSS but the video does not play.
At the moment I get the error that videoFile[0] is undefined.
Top comments (3)
I don't have any experience with react-simple-idle-monitor, but I'll give it a go.
Generally, you won't ever have to do a
document.getElementById
in React - instead, let the data (the state) drive that for you.refs would be ok here (instead of document.getElementById), but I think there might be a better way (though I could be wrong - more info below):
The idea is to use the IdleMonitor to set state in the class, and then use that state to show and/or hide the video, like this:
So notice that I just set an "idle" state on start or stop, and then use that idle state to "gate" the screensaver from showing up or not at all - and then the screensaver itself can be set to just autoplay, and it won't even be in the DOM until it's set to idle.
The one place this doesn't make sense is if the screensaver is like, a really big file - and so you want it to load up in the dom at the start, and be instantly ready to play. In that case, I would try to think of a way to use the new
idle
state to set an attribute to play it.Does that help at all?
Oh You GENIUS!!!! Thank you very much. Worked like a charm :D
Nice!