Problem fixed and codes updated
Put youtubeReady Promise into another file(youtubeReady.js) and import from it :
const YTReady = new Promise( (resolve) => {
window.onYouTubeIframeAPIReady = () => resolve(window.YT);
});
export default YTReady;
Code updated marked files
Post updated:
I have tried the potential solution according to HMR's answer.
But it didn't work...
(codes below have been updated as well)
I replace the original codes:
this.player = new Promise (...)
this.player.then(...)
with a new approach
const youtubeReady = new Promise(...)
youtubeReady.then(...)
The result is the video did not even shows up in firstCmp nor secondCmp class obj(constructor).
I used console.log(this) in componentDidMount() of these 2 components and no video was loaded.
Did I do it right? or I missed something?
Original Post content
Well, last few days I solved my previous problems to get Youtube-api working via mouseOver/mouseLeave events.
Now I got a new problem which I am struggling with for 2 days.
I got 3 components.
First to set script tag to get api (app.js) :
import React, {Component} from "react";
import ReactDom from "react-dom";
import './app.scss';
import FirstCmp from './firstCmp.js'
import secondCmp from './secondCmp.js'
class App extends Component {
componentDidMount() {
let tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
let firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
render() {
return (
<div id="app">
<FirstCmp />
<SecondCmp />
</div>
)
}
}
ReactDom.render(<App/>, document.getElementById('root'))
Then to create a video (firstCmp.js):
import React, { Component } from 'react';
import style from './firstCmp.scss';
import YTReady from './resource/youtubeReady';
export default class FirstCmp extends Component {
constructor(props) {
super(props);
// just for example, not real code
this.state = {
iframeId: "myIframe",
src: "src"
}
}
componentDidMount() {
let youtubeReady = YTReady;
youtubeReady.then( (YT) => {
this.player = new YT.Player(this.state.iframeId, {
events: {
'onReady': () => this.onPlayerReady(),
'onStateChange': () => this.onPlayerStateChange()
}
})
})
}
mouseOver() {
this.player.playVideo();
}
mouseLeave() {
this.player.pauseVideo();
}
render() {
return (
<section className={style.firstCmpContent}>
<iframe
id={this.state.iframeId}
src={`${this.state.src}`}
frameBorder="0"
style={style.firstCmp}
onMouseOver={ () => this.mouseOver() }
onMouseLeave={ () => this.mouseLeave() } >
</iframe>
</section>
);
}
}
So far so good. The first video works fine. Until I create the second video...(secondCmp.js)
import React, { Component } from "react";
import style from './secondCmp.scss';
import YTReady from './resource/youtubeReady';
export default class SecondCmp extends Component {
constructor(props) {
super(props);
// just for example, not real code
this.state = {
iframeId: "myIframe",
src: "src"
}
}
componentDidMount() {
let youtubeReady = YTReady;
youtubeReady.then( (YT) => {
this.player = new YT.Player(iframeId, {
events: {
'onReady': () => this.onPlayerReady(),
'onStateChange': () => this.onPlayerStateChange()
}
})
})
}
mouseOver() {
this.player.playVideo();
}
mouseLeave() {
this.player.pauseVideo();
}
render() {
return (
<section className={style.secondCmpContent}>
<iframe
id={this.state.iframeId}
src={`${this.state.src}`}
frameBorder="0"
style={style.secondCmp}
onMouseOver={ () => this.mouseOver() }
onMouseLeave={ () => this.mouseLeave() } >
</iframe>
</section>
);
}
}
Now, only the second video works, the first one gets promise pending!
If I create a third video, then the second and first get promise pending and only the new one(third) is working and so on.
How do I fix this problem?