'How to update state so that my timer will run after video load
I am newbie on react. I am bit stuck in problem and need to know some pointers regarding state update.
PROBLEM: I am making the video on load and add the skip button for removing the video from screen. Video will be played through HTML under the modal. Problem is my video load in 2 or 3 sec after the page refresh and modal will open prior to load video. I have set the timer from 5 seconds which is in reverse format like 5, 4, 3, 2, 1, skip
But due to slow/late video load, timer run in background and in front side when video display sometime it sees 3, 2, 1, skip
What I am looking for is when my video start load then only my timer function trigger.
I have tried onLoad(), onStart() to update the flag state from false to true and on componentDidMount -> load the page according to the state but not getting luck
This is my code:
export default class FullScreenAds extends React.Component {
constructor(props) {
super(props);
this.state = {
isFullPageVideoModalEnabled: false,
timerForVideo: 7,
isDisabled: true,
};
},
async componentDidMount() {
const uuid = Math.round((new Date()).getTime() / 1000);
let getUserSession = localStorage.getItem("gid");
if (getUserSession === null || getUserSession.length < 1) {
localStorage.setItem("gid", uuid);
}
this.setState({
isFullPageVideoModalEnabled: true,
getSession: getUserSession
})
this.startTimer()
},
async startTimer() {
// await sleep(3000);
this.timer = setInterval(() => {
const { timerForVideo } = this.state
if (timerForAds > 0) {
this.setState(({ timerForVideo }) => ({
timerForVideo: timerForVideo - 1
}))
}
if (timerForAds === 0) {
this.setState({ isDisabled: false })
clearInterval(this.timer)
}
}, 1000)
}
componentWillUnmount() {
clearInterval(this.timer)
}
render() {
return (
// run the modal based on state and load the video
<video width="100%" height="auto" autoPlay playsInline loop>
<source type="video/mp4" src="video/src/url" />
</video>
)
}
}
Solution 1:[1]
Create a reference with React.createRef() and attach the reference to the video, then listen for the onplay event on the video and start the timer when the onplay event fires:
Try this:
export default class FullScreenAds extends React.Component {
constructor(props) {
super(props);
this.videoRef = React.createRef()
this.state = {
isFullPageVideoModalEnabled: false,
timerForVideo: 7,
isDisabled: true,
};
},
async componentDidMount() {
const uuid = Math.round((new Date()).getTime() / 1000);
let getUserSession = localStorage.getItem("gid");
if (getUserSession === null || getUserSession.length < 1) {
localStorage.setItem("gid", uuid);
}
this.setState({
isFullPageVideoModalEnabled: true,
getSession: getUserSession
})
this.videoRef.current.onplay = () => this.startTimer();
},
async startTimer() {
// await sleep(3000);
this.timer = setInterval(() => {
const { timerForVideo } = this.state
if (timerForAds > 0) {
this.setState(({ timerForVideo }) => ({
timerForVideo: timerForVideo - 1
}))
}
if (timerForAds === 0) {
this.setState({ isDisabled: false })
clearInterval(this.timer)
}
}, 1000)
}
componentWillUnmount() {
clearInterval(this.timer)
}
render() {
return (
// run the modal based on state and load the video
<video ref={this.videoRef} width="100%" height="auto" autoPlay playsInline loop>
<source type="video/mp4" src="video/src/url" />
</video>
)
}
}
Solution 2:[2]
Or you can try using functional component with hooks.
Something like this:
export const FullScreenAds = () => {
const [state, setState] = React.useState({
isFullPageVideoModalEnabled: false,
timerForVideo: 7,
isDisabled: true,
});
const videoRef = React.useRef();
const timerRef = React.useRef();
const startTimer = () => {
timerRef.current = setInterval(() => {
const { timerForVideo } = state;
if (timerForAds > 0) {
setState({
...state,
timerForVideo: state.timerForVideo - 1,
});
}
if (timerForAds === 0) {
setState({ ...state, isDisabled: false });
clearInterval(this.timer);
}
}, 1000);
};
useEffect(() => {
const uuid = Math.round(new Date().getTime() / 1000);
let getUserSession = localStorage.getItem("gid");
if (getUserSession === null || getUserSession.length < 1) {
localStorage.setItem("gid", uuid);
}
setState({
...state,
isFullPageVideoModalEnabled: true,
getSession: getUserSession,
});
videoRef.current.onplay = startTimer;
return clearInterval(timerRef.current);
}, []);
return (
<video
ref={this.videoRef}
width="100%"
height="auto"
autoPlay
playsInline
loop
>
<source type="video/mp4" src="video/src/url" />
</video>
);
};
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | PatersonCode |
