是什麼
簡稱HOC,全稱 High Order Component。作用是給react組件增減props屬性。
怎樣用
為何不先說怎樣寫?恩,由於你實在已用過了,舉個例子:
// App.js
import {connect} from 'react-redux';
class App extends React.Component {
render() {}
}
export default connect()(App);
熟習不?redux的連接器。不過筆者有潔癖,喜好用裝潢器:
// App.js
import {connect} from 'react-redux';
@connect()
export class App extends React.Component {
render() {}
}
最先寫
從connect()()
能夠看出,connect是一個函數,返回值是個react組件。這麼智慧,好信服本身啊。
雛形
// myHoc.js
import React from 'react';
export const myHoc = () => {
return (Wrapped) => {
class Hoc extends React.Component {
render() {
return <Wrapped {...this.props}>;
}
}
return Hoc;
};
};
是的,高階組件的雛形,就是函數里隱蔽了一個react組件,而參數Wrapped
是什麼?就是下面被裝潢的組件:
// App.js
@myHoc()
export class App extends React.Component {
render() {}
}
恩恩,表現形式和redux的connect如出一轍。
所以用了高階組件后,export出去的不再是你本身寫的App(Class),而是末了一個高階。
增添props屬性
好的啦,如今用myHoc給App組件加點料:
// myHoc.js
export const myHoc = () => {
return (Wrapped) => {
class Hoc extends React.Component {
render() {
return <Wrapped {...this.props} whoAmI="原罪">;
}
}
return Hoc;
};
};
// App.js
@myHoc()
export class App extends React.Component {
render() {
return <div>{this.props.whoAmI}</div>;
}
}
寧神,如今瀏覽器里已把我的名字 原罪 打印出來了。
多個高階組件
是的,寫完一個hoc以後,你就會有寫第二個的需求,那就一升引呢:
// App.js
@myHoc()
@yourHoc()
@hisHoc()
@herHoc()
export class App extends React.Component {
render() {
return <div>{this.props.whoAmI}</div>;
}
}
這就是筆者為啥要用裝潢器的緣由,簡約,看起來愜意,寫起來快,我們看一下另一種寫法:
class App extends React.Component {
render() {}
}
export default myHoc()(yourHoc()(hisHoc()(herHoc()(App))));
本身體味,格式化一下吧:
class App extends React.Component {
render() {}
}
let hoc;
hoc = herHoc()(App);
hoc = hisHoc()(hoc);
hoc = yourHoc()(hoc);
hoc = myHoc()(hoc);
export default hoc;
寫得累不?來,給你條毛巾擦擦汗
帶參數
對了,hoc能夠吸收參數,比方如許:
// App.js
@myHoc('原罪2號')
export class App extends React.Component {
render() {
return <div>{this.props.whoAmI}</div>;
}
}
那高階組件怎樣接呢?
// myHoc.js
export const myHoc = (name) => {
return (Wrapped) => {
class Hoc extends React.Component {
render() {
return <Wrapped {...this.props} whoAmI={name}>;
}
}
return Hoc;
};
};
我把hoc吸收到的參數又返還給了App組件,那如今瀏覽器輸出的就是:原罪2號。
不帶參數
如今,你能夠有一個斗膽勇敢的插法..哦不,主意,就是@myHoc背面能夠不加括號嗎?是哦,看前面幾個案例,都是@myHoc()
。好的,看我的:
// myHoc.js
export const myHoc = (Wrapped) => {
class Hoc extends React.Component {
render() {
return <Wrapped {...this.props} whoAmI="原罪">;
}
}
return Hoc;
};
// App.js
@myHoc
export class App extends React.Component {
render() {
return <div>{this.props.whoAmI}</div>;
}
}
仔細的看官看一下myHoc.js和帶參數的時刻有什麼區別。是的,少了一層回調。假如你的高階組件不須要帶參數,如許寫也是很ok的。
操控原組件
你能夠須要拿被裝潢的組件的state數據或許實行它的要領。那末須要豎立一個援用:
// myHoc.js
import React from 'react';
export const myHoc = () => {
return (Wrapped) => {
class Hoc extends React.Component {
appRef = null;
componentDidMount() {
// 能夠對被myHoc裝潢的組件做羞羞的事變了,:)
console.log(this.appRef);
}
render() {
return <Wrapped {...this.props} ref={(app) => {this.appRef = app}} >;
}
}
return Hoc;
};
};
注重: 在多個高階組件裝潢同一個組件的情況下,此法並不見效。你拿到的ref是上一個高階組件的函數中暫時天生的組件。而且在大多數情況下,你並不知道某個組件會被多少個高階裝潢!
總結
當項目中多處用到某個邏輯要領,然則這個邏輯不能放到util里的時刻,HOC合適你。一個HOC最好只做一件事,如許保護輕易