如果一個函數操作其他函數,即將其他函數作爲參數或將函數作爲返回值,將其稱爲高階函數。
高階組件(high-order component)類似於高階函數,接收組件作爲輸入,輸出一個新的組件。
實現高階組件的方法有如下兩種。
- 屬性代理(props proxy)。屬性組件通過被包裹的 React 組件來操作 props。
- 反向代理(inheritance inversion)。高階組件繼承於被包裹的 React 組件。
1. 屬性代理
屬性代理是常見高階組件的實現方法。
const firstComponent = (SecondComponent) => {
return class extends Component {
render() {
return (
<SecondComponent
{...props}
/>
)
}
}
}
export default firstComponent ;
//在 render 方法中返回傳入 SecondComponent的 React 組件。這樣就可以通過高階組件來傳遞 props,這種方法即爲屬性代理。
原始組件想要具備高階組件對它的修飾,有兩種方式。
方式一:
export default firstComponent;
class MyComponent extends Component {
}
export default firstComponent(MyComponent);
方式二:
ES6 添加了 decorator 的屬性,我們可以通過 decorator 來轉換,以此簡化高階組件的調用。
@firstComponent
class MyComponent extends Component {
}
export default MyComponent;
這樣組件就可以一層層地作爲參數被調用,原始組件就具備了高階組件對它的修飾。這樣保持了單個組件封裝性的同時還保留了易用性。
2. 反向繼承代理
反向繼承是另一種構建高階組件的方法。因爲被動地繼承了 WrappedComponent,所有的調用都會反向。
const firstComponent = (SecondComponent) => {
return class extends WrappedComponent {
render() {
return super.render();
}
}
}
export default MyContainer;
看一下實際react組件用法:
將公共的邏輯拿到外層組件,處理好後以屬性的方式傳遞給原本的組件,爲此高階組件就是一個 React 組件包裹着另外一個 React 組件
import React from 'react';
let local = (key)=>(Component)=>{
return class HighOrderComponent extends React.Component{
constructor(){
super();
this.state = {val:''}
}
componentDidMount(){
let username = localStorage.getItem(key)||'';
this.setState({
val:username
})
}
render(){
return <Component {...this.state}/>
}
}
};
export default local;
import Local from './Local'
class Username extends React.Component {
render(){
return(
<div>
<input type="text" value={this.props.val} onChange={()=>{}}/>
</div>)
}
}
export default Local('username')(Username);