我有一个主要组件App
,它有两个子组件Player
和VideoList
,其中Player
是react-player
的包装,严重基于react-player
演示。
Player
有一个方法renderLoadButton()
,可以创建一个按钮,在点击时加载特定视频。我想在我的VideoList
组件中有几个这样的按钮。
我正在尝试将renderLoadButton()
函数传递到父组件,然后向下传递到我可以调用它的VideoList
组件。
以下是父组件的render()
函数的代码。我的<Player/>
和<VideoList/>
组件都在这里实例化了。
我在评论中提到的行上收到以下错误。
TypeError:无法读取未定义
的属性'renderLoadButton'
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>
);
}
答案 0 :(得分:1)
根据您提供的代码,您正在做正确的我已经创建了与您相似的工作模型它正常工作: https://codesandbox.io/s/6y5p9woqq3
您可以将代码添加到沙箱中,以便我们能够找出问题所在。
修改强>
您的代码问题不是index.js
,而是根据您的最小代码在VideoList.js
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;
在这里,您尝试返回一个包含函数而不是原始jsx的道具,以便更清晰地尝试控制台日志记录
console.log("dd",this.props.callback)
它显示了一个返回this.player.renderLoadButton
函数的对象。因此,当您尝试返回它时,它只返回一个无法渲染的函数,这会导致错误。
因此,如果你必须传递返回jsx的函数,请不要使用ref.Create一个新的obj或Player类的实例,并从中提取函数,然后将其作为prop传递给videoList,并将其调用为render返回。
因此您的App
组件应如下所示:
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>
);
}
}
然后你的VideoList
看起来像:
class VideoList extends Component {
render() {
console.log("dd");
return (
<div>
{ this.props.func('www.something.com','BUTTON') }
</div>
)
}
}
export default VideoList;
这是工作代码:https://codesandbox.io/s/jpqnxwyyy
编辑2:
我不认为这样可能。你可以做的一件事是在每个地方使用相同的jsx,并使用另一个函数作为道具,每个地方再次调用。像这样:https://codesandbox.io/s/7zwyl0yp3j
答案 1 :(得分:0)
使用this.METHOD_NAME时,您必须使用初始方法!
constructor(props){
super(props);
this.renderLoadButton = this.renderLoadButton.bind(this);
}
renderLoadButton(x,y){
console.log(x,y); // for example
}
render(){
return(
...
<VideoList callback={this.renderLoadButton}/>
...
)
}
如果你想使用其他类的静态方法,首先导入类然后使用这样的静态方法:
import Player from 'PLAYER_FILE_LOCATION';
.
.
.
.
.
render(){
return(
...
<VideoList callback={Player.renderLoadButton}/>
...
)
}