爲何要用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