javascript - 如何与 React 中的子组件通信?
问题描述
我有一个父组件VideoPlayer
,它有条件地呈现许多不同的视频播放器提供商之一(想想 videoJS、JW 播放器等) - 所以VideoJSPlayer
,JWPlayer
等等。
父组件监视视频何时播放完毕并需要让子组件知道是时候播放新视频了。每个不同的视频提供者都有不同的 JS 库/API,我可能会引用它们。父组件还呈现共享组件,如播放按钮、跳过按钮等。
我怎样才能最容易地让父组件保持类似的功能并确保子组件只处理特定于库的操作?
例如,如果单击共享的跳过按钮,我应该如何从父级调用它?我目前正在使用postMessage()
,但感觉不太对劲。
这是一些最小的代码。实际上,父组件维护和共享的东西不止一件事。
class Player extends React.Component {
constructor(props) {
super(props)
this.state = {
props.videos,
activeIndex: 0,
activeVideo: props.videos[0]
}
}
loadNextVideo() {
// how to communicate to VideoJSPlayer and JWPlayer?
}
render() {
const playerCode = this.props.playerCode
return (
<div>
{
playerCode === 'videojs' ?
<VideoJSPlayer/> :
playerCode === 'jwplayer' ?
<JWPlayer/> : null
}
<SkipButton
activeVideo={this.state.activeVideo}
onClick={() => this.loadNextVideo()}/>
)
}
}
解决方案
我会开始指出一些糟糕的模式:
- 从道具(props.videos)派生的状态;
大多数时候你不应该重复道具来声明;
- 从其他状态派生的状态(activeVideo);
activeVideo
不是必要状态。activeIndex
它是从and派生的计算值props.videos
。是冗余状态,只需要保存当前视频的引用即可;
还有一些小技巧;
constructor
几年不需要,您可以直接在外面声明您的州;- 将您的方法声明为箭头函数是一种实用且更简洁的绑定方式
this
;
鉴于此,您loadNextVideo
将更新到下一个索引。VideoJSPlayer
并且JWPlayer
应该作为道具接收,activeVideo
并且loadNextVideo
应该在视频播放完毕时在这些组件中调用;
class Player extends React.Component {
state = {
activeIndex = 0
}
loadNextVideo = () => {
// you might add some validation if it's the last index
if (this.props.videos.length - 1 === this.state.activeIndex) return
this.setState(({ activeIndex }) => ({ activeIndex: activeIndex + 1 }))
}
render() {
const { activeIndex } = this.state
const activeVideo = this.props.videos[activeIndex]
const playerCode = this.props.playerCode
return (
<div>
{
playerCode === 'videojs' ?
<VideoJSPlayer activeVideo={ activeVideo } loadNextVideo={ this.loadNextVideo } /> :
playerCode === 'jwplayer' ?
<JWPlayer activeVideo={ activeVideo } loadNextVideo={ this.loadNextVideo } /> : null
}
<SkipButton
activeVideo={ this.state.activeVideo }
onClick={ this.loadNextVideo }/>
</div>
)
}
}
推荐阅读
- php - 致命错误:未捕获错误:调用未定义函数 wp_get_current_user()
- json - Xamarin.Android - 如何从网站获取 JSON
- r - 在 R 中保存雷达图
- python - 为什么使用 3d 数组的 ndimage.convolve 会产生 3d 数组而不是 2d?
- drools - Drools - 何时使用多个 kie 会话?
- javascript - mongodb 找不到匹配项
- javascript - 试图为我的机器人制作一个不和谐的歌曲队列
- git - 基于 yaml 管道上的资源的条件
- video-streaming - WebRTC - WebRTC: ICE failed, add a STUN server and see about:webrtc 了解更多详情
- asp.net-mvc - 如何在使用 ASP.NET MVC 的 Plesk 托管中使用 Rotativa 生成 PDF?