Skip to content

Extracting play function of react-youtube in state to use in button oncluck results in CORS

I am using react-youtube library from npm in my react project. I want to play and pause YouTube video on button onClick event.
I have tried extracting the event as well as function from YouTube component to state, and later calling that function via a button onClick but it results in cross origin error “Uncaught Error: A cross-origin error was thrown. React doesn’t have access to the actual error object in development. See https://reactjs.org/link/crossorigin-error for more.”
What am I doing wrong? And how do I fire YouTube component event from another component like a button?

import './App.css';
import YouTube from 'react-youtube';
import React, { Component } from 'react';


class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      playerPlayVideo: () => {}
    }
    this.videoOnReady = this.videoOnReady.bind(this);
  }

  videoOnReady(event) {
    // access to player in all event handlers via event.target
    this.setState({
      playerPlayVideo: event.target.playVideo
    });
  }

  render() { 
    const opts = {
      height: '390',
      width: '640',
    };

    return ( 
      <div>
        <YouTube videoId="2g811Eo7K8U" opts={opts} onReady={this.videoOnReady} />
        <button onClick={this.state.playerPlayVideo}>play</button>
      </div>
    );
  }
}
 
export default App;

Answer

‘react-youtube’ uses YouTube Api internally. The actions that the player performs are based on event.target. You are saving the callback function playVideo in a state, which is possibly causing scope issues.

In this case instead of storing the ‘playVideo’ function in state you can simply store event.target object in state.

this.state = {
  playerPlayVideo: {},
};

Then on button click you can simply call playVideo like this,

<button onClick={() => this.state.playerPlayVideo.playVideo()}>
   play
</button>

This works!! I have tested it.

You can then make this better by having a toggle state logic as well since you are now storing event.target in state directly. Therefore you can now call both ‘playVideo’ as well as ‘pauseVideo’