用到的緣由是由於公司最近要作一個釘釘oa系統,選的技術棧則是比較火熱的react,開發中遇到的問題就是代碼如何複用問題,由於react官方已經不推薦使用Mixins,而是推薦了高階組件這種方式,接下來咱們就來聊聊它javascript
a higher-order component is a function that takes a component and returns a new component.java
意思是:高階組件是一個函數,它接受一個組件並返回一個新組件react
舉個例子🌰:假設咱們如今須要實現一個登錄註冊功能,爲了方便,咱們把用戶(user)存在localStorage下,若是發生操做行爲就會先去檢測下有沒有user (固然現實開發不能夠這樣作的)函數
代碼實現:ui
// 登錄
function login() {
let user = localStorage.getItem('user');
console.log('login ' + login);
}
// 註冊
function resgister() {
let user = localStorage.getItem('user');
console.log('resgister ' + user);
}
login();
resgister();
複製代碼
上面的例子咱們發現都有一句如出一轍的冗餘代碼,這顯然對於有代碼潔癖的人簡直不能忍,那就動手將它抽離出來捱打吧this
代碼實現:spa
// 登錄
function login() {
console.log('login ' + login);
}
// 註冊
function resgister() {
console.log('resgister ' + user);
}
// 抽離出來的中間函數
function wrapUser(Wrapfunc) {
let Newfunc = () => {
let user = localStorage.getItem('user');
Wrapfunc(user);
};
return Newfunc;
}
// 調用
login = wrapUser(login);
resgister = wrapUser(resgister);
login();
resgister();
複製代碼
以上的例子咱們能夠把wrapUser稱爲高階函數,它負責的是就是把咱們共用代碼抽離的出來,這樣簡化了複用的代碼,不少同窗會問,上面的代碼量不是更加多了嗎?可是實際開發項目時候複用的代碼可不是這麼一丁點,還有可能有其餘需求產生複用這段代碼就好比產品臨時加了須要忘記密碼的功能code
代碼以下:component
function forgetPassWord(){
console.log('forgetPassWord ' + user);
}
forgetPassWord = wrapUser(forgetPassWord);
forgetPassWord()
複製代碼
上面的代碼若是用react方式是怎麼實現的xml
Login組件
import React, {Component} from 'react'
class Login extends Component {
constructor(props) {
super(props);
this.state = {
user: ''
}
}
componentWillMount() {
let user = localStorage.getItem('user');
this.setState({
user
})
}
render() {
return (
<div>login{this.state.user}</div>
)
}
}
export default Login;
複製代碼
Register組件
import React, {Component} from 'react'
class Register extends Component {
constructor(props) {
super(props);
this.state = {
user: ''
}
}
componentWillMount() {
let user = localStorage.getItem('user');
this.setState({
user
})
}
render() {
return (
<div>register{this.state.user}</div>
)
}
}
export default Register;
複製代碼
能夠看到這個組件這兩個組件都有複用的代碼,因此咱們上述高階函數wrapUser的例子來實現高階組件
WrapUser高階組件
import React, {Component} from 'react'
export default (WrapComponent) => {
// 這裏的WrapComponent是咱們傳進來的組件
class NewComponent extends Component {
constructor() {
super();
this.state = {
user: ''
}
}
componentWillMount() {
let user = localStorage.getItem('user');
this.setState({
user
})
}
render() {
return <WrapComponent user={this.state.user}/> } } return NewComponent } 複製代碼
上述的代碼是聲明一個函數這個函數從參數是接收一個組件,而後return回去一個新的組件,咋一看有同窗發現這個很像是父組件套了一個子組件,沒錯實際上就是這樣的,並且他們的通訊也是父子組件通訊
這樣咱們來簡化下login組件和register組件
Login組件
import React, {Component} from 'react';
import WrapUser from 'WrapUser';
class Login extends Component {
render() {
return (
<div>login{this.props.user}</div>
)
}
}
Login = WrapUser(Login);
export default Login;
複製代碼
Register組件
import React, {Component} from 'react';
import WrapUser from 'WrapUser';
class Register extends Component {
render() {
return (
<div>register{this.props.user}</div>
)
}
}
Register = WrapUser(Register);
export default Register;
複製代碼
到這裏咱們代碼複用性的問題就解決了,高階組件實際就是一個函數,並不要被它的名稱所嚇倒