为何要用hoc的缘由在官方文档已经给出,就是为了抽出多个组件相同的部分来,具体解释在https://reactjs.org/docs/higher-order-components.html,在hoc函数中返回一个匿名的类,若是传入的是一个组件名,其余参数能够经过给匿名类传参数的形式获取,以个人hoc代码为例,我要实现的功能是封装video和audio的大部分相同功能,细节部分省略:html
function mediaCommonComponent(MediaComponent) { // ...and returns another component... return class extends React.Component { constructor(props) { super(props); this.state={
someinitialparam
} } componentDidMount() { dosomething } //各个函数 render() {
//从全部传入的方法和属性中解构出方法和属性,把不须要的单独解构,这样须要的就直接用...的形式附加到组件上
//这么作是由于有些方法和不支持的属性加在原生的组件上可能会报错
const {dont need1,dont need2,...need}=this.props;
//再把这个方法解构到组件上
//这是没有子节点的状况就可使用单标签的形式,若是有子节点还可使用双标签的形式,例如<MediaComponent {...need}/>我是子节点</MediaComponent>
return <MediaComponent {...need}/>
这里就定义好了hoc函数,这没什么特别的。官方教程都有。而后是使用这个hoc组件,注意,由于我Hoc函数要求接收的是一个组件名,因此这里必须传入一个组件名称react
class MediaPlay extends React.Component{
constructor(){
super()
this.state={}
}
//我把引入hoc放在这里来执行,官方文档说放这里或者别的钩子都是没问题的,可是不能放在render里面来引入hoc,由于每次render都会是一个新的组件
componentDidMount(){
//我经过一个type来决定生成的是video仍是audio标签
let media_type="";
media_type=this.props.type===0?'VideoComponent':'AudioComponent';
this.mediaComponent=mediaCommonComponent(media_type)
}
render(){
return <this.mediaComponent {...this.props} />
}
}
最后是video和audio标签组件:ide
class VideoComponent extends React.Component{
render(){
//这里获取到的属性实际就是在MediaPlay标签中传入的全部数据
return <video {...this.props} ></video>
}
}
class AudioComponent extends React.Component{
render(){
return <audio {...this.props}></audio>
}
}
还有一个问题。就是必需要使用原生的元素的某些方法,好比个人video,我要在公共组件的钩子componentDidMount里执行他们的play方法,由于没有触发事件,就必须用ref来获取元素引用,可是在这个公共组件里面是拿不到真实的元素的。对公共组件的ref属性引用的是公共的类,这时候就须要一个小技巧,官方文档给出的。可是有点费解。个人理解以下:函数
react的组件ref引用能够以函数形式引用 ,如ref={ele=>this.ele=ele},那么就能够利用react子组件向父组件传递数据是经过调用父组件的方法而且传入相应数据给父组件,这样在 video组件里面能够这样写this
<video ref={this.props.getCurrRef}>,而这个getCurrRef就至关于获取了组件ref里面的函数,固然也就能获取到其中引用的组件,而后在mediaCommonComponent传入getCurrRef方法来获取数据,代码以下spa
<mediaCommonComponent getCurrRef={mediaEle=>this.mediaEle=mediaEle}>,而后就能够在组件的componentDidMount里使用this.mediaEle来表示video标签了。audio相似的方式处理code