1

I am having trouble passing an URL ref to my onClick event handler changeTrack. I am trying to change the track URL loaded into the media player from the URL of the onClicked show.

My current code gives me the following error.

TypeError: Cannot read property 'changeTrack' of undefined

I have tried several different methods of binding to this, such as

onClick={ this.changeTrack.bind(this, show.url )}
onClick={() => this.changeTrack(showurl)}

as well as defining show.url as showlink and using this to define a property for changeTrack.

let showlink = show.url;

I would like to know if I am on the right track, or if I am entirely misinterpreting the purpose of refs in React.

Here is my code:

   class MediaPlayer extends Component{
    constructor(props) {
        super(props);
        this.state = { 
          shows: [],           
          showURL: "https://www.mixcloud.com/NTSRadio/nosedrip-9th-january-2017/",`
        };
     this.changeTrack = this.changeTrack.bind(this);
    }

  changeTrack (url){
      let newUrl = url;
      this.setState({ showURL: newUrl});
  };



   componentDidMount() {
    const url = `https://api.mixcloud.com/NTSRadio/cloudcasts/?limit=${this.state.limit}`;
    const showsindex = fetch(url)
      .then(response => response.json())
      .then(data => this.setState({
        term: '',
        name: data.name,
        shows: data.data,
       }))
      .catch(e => console.log('error', e));
  }

render(){
   return (
     <div className="main">          
       <div className="grid">
          {this.state.shows.map(function(show) {
             let showlink = show.url;
               return (   
                <div className="show">   
                   <div className="showname" ref={show.url} onClick={() => this.changeTrack(showurl)}>
                      {show.name}
                   </div>
                </div>
             );
           })}
       </div>   
       <div className="mixcloud-player">
          <ReactPlayer  url={this.state.showURL} width='100%'
            height='60px' controls="true"/>
        </div>
    </div>
   );
}
Roy Scheffers
  • 3,255
  • 10
  • 28
  • 33
Mcas4150
  • 11
  • 6

1 Answers1

2

The function expression inside your render function creates a new lexical scope. Use a fat arrow function instead for this to reference your component instance. Also assign keys to the children to help with reconciliation:

{this.state.shows.map( show => 
    <div key={show.name} className="show">   
        <div className="showname" ref={show.url} onClick={() => this.changeTrack(show.url)}>
            {show.name}
        </div>
    </div>
)}
trueter
  • 126
  • 4