Reputation: 331
I have a main component, App
, which has two child components, Player
, and VideoList
, where Player
is a wrapper around react-player
, heavily based off of the react-player
demo.
Player
has a method renderLoadButton()
which creates a button that loads a particular video when clicked. I would like to have several of these buttons inside of my VideoList
component.
I am attempting to pass the renderLoadButton()
function up into the parent component, and then down into the VideoList
component where I can call it.
Here is the code for render()
function of the parent component. Both my <Player/>
and <VideoList/>
components instantiated here.
I get the following error on the line mentioned in the comment.
TypeError: Cannot read property 'renderLoadButton' of undefined
render() {
const dragHandlers = {onStart: this.onStart, onStop: this.onStop};
const {deltaPosition, controlledPosition} = this.state;
return (
<div className="App">
<div className="fullscreen">
<Draggable handle="strong" bounds={'body'}{...dragHandlers}>
<div style={{position: 'absolute', bottom: '30%', right: '50%'}} className="video-box no-cursor">
<Player ref={instance=>{this.player = instance}} title="VIDEO" url='https://streamable.com/nfec3'/>
</div>
</Draggable>
<Draggable handle="strong" bounds={'body'}{...dragHandlers}>
<div>
{/*Error on the following line*/}
<VideoList callback = {(x,y)=> this.player.renderLoadButton(x,y)}/>
</div>
</Draggable>
</div>
<div className="App-footer">
<img src={vinyl} className="App-logo" alt="logo" />
<h1>Radio</h1>
</div>
</div>
);
}
Upvotes: 0
Views: 2078
Reputation: 5466
As per the code you provided you are doing it right i have created similar working model as yours it is working fine: https://codesandbox.io/s/6y5p9woqq3
You can add your code to sandbox so that we will able to figure out what is the problem.
Edit
The Problem with your code is not index.js
but is in VideoList.js
as per your minimal code
VideoList.js
:
import React, { Component } from "react";
class VideoList extends Component {
render() {
console.log("dd");
return this.props.callback('www.something.com','BUTTON');
}
}
export default VideoList;
Here you are trying to return a prop which contains a function not the original jsx for better clarity try console logging like this
console.log("dd",this.props.callback)
which shows a object returning your this.player.renderLoadButton
function. so when you are trying to return it which returns just a function which cannot be rendered it is causing errors.
So if you have to pass that function which returns jsx don't use ref.Create a new obj or instance of Player class and extract the function from it and then pass it as prop to the videoList and the call it in render return.
so your App
component should look like:
class App extends Component {
render() {
const obj = new Player
const func = obj.renderLoadButton
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Player title="VIDEO" url='https://streamable.com/nfec3'/>
<VideoList func={func} />
</div>
);
}
}
then your VideoList
looks like:
class VideoList extends Component {
render() {
console.log("dd");
return (
<div>
{ this.props.func('www.something.com','BUTTON') }
</div>
)
}
}
export default VideoList;
here is working code :https://codesandbox.io/s/jpqnxwyyy
Edit 2:
i don't think it is possible that way. one thing you can do is use the same jsx every where and use the another function as props every where to call again. like this: https://codesandbox.io/s/7zwyl0yp3j
Upvotes: 1