一航瞭、react 高階組件 Higher-Order Components (簡稱為 HOC)
高階組件(HOC)是 React 中用于復用組件邏輯的一種高級技巧网持。
HOC 自身不是 React API 的一部分溺职,它是一種基于 React 的組合特性而形成的設(shè)計模式返劲。
高階函數(shù):接受單個或多個函數(shù)作為參數(shù)并返回一個新函數(shù)的函數(shù)
高階組件:接受單個或多個組件作為參數(shù)并返回一個新組件的函數(shù)
二唉窃、HOC 的種類
1. 屬性代理
通過高階組件將屬性傳遞給被包裝的原始組件剪菱,在原始組件中通過 this.props
操作屬性
- 在組件中使用高階組件
import React, { Component } from "react";
import HeightComponent from './pages/HeightComponent'
class App extends Component {
render() {
return (
<>
<HeightComponent a="a" />
</>
);
}
}
export default App;
- 高階組件
定義高階組件并在高階組件中做通用邏輯處理
import React, { Component } from "react";
// 定義高階組件
const HocPropsProxy = (TargetComponent) => {
// 返回容器組件
return class Enhance extends Component {
constructor(props) {
super(props);
this.state = {
b: "b",
};
}
render() {
return (
<>
<TargetComponent {...this.props} {...this.state} />
</>
);
}
};
};
// 定義原始組件
class Test extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<>
<div>
<div>hello world</div>
<div>a: {this.props.a}</div>
<div>b: {this.props.b}</div>
</div>
</>
);
}
}
// 使用高階組件包裝原始組件
export default HocPropsProxy(Test);
2. 反向繼承
在高階組件中摩瞎,讓容器組件繼承原始組件
- 在組件中使用高階組件
import React, { Component } from "react";
import HeightComponent from './pages/HeightComponent'
class App extends Component {
render() {
return (
<>
<HeightComponent a="a" />
</>
);
}
}
export default App;
- 定義高階組件并在高階組件中做通用邏輯處理
import React, { Component } from "react";
// 定義高階組件
const HocPropsProxy = (TargetComponent) => {
// 返回容器組件
return class Enhance extends TargetComponent {
constructor(props) {
super(props);
this.state = {
b: "b",
};
}
render() {
return super.render()
}
};
};
// 定義原始組件
class Test extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<>
<div>
<div>hello world</div>
<div>a: {this.props.a}</div> {/* 來自繼承 */}
<div>b: {this.state.b}</div>
</div>
</>
);
}
}
// 使用高階組件包裝原始組件
export default HocPropsProxy(Test);
三、HOC 常用示例
- redux 中的 connect
- react-router 中的 withRouter
四孝常、高階組件的拓展示例(分離通用樣式和通用模板)
import React, { Component } from "react";
import styled from "styled-components";
// 添加公共樣式
const Wrapper = styled.div`
height: 100vh;
width: 94%;
margin-left: 3%;
font-size: 24px;
background: #f3f3f3;
color: #666;
`;
// 定義高階組件
const CommonCssWrapper = (TargetComponent) => {
// 返回容器組件
return class Enhance extends Component {
render() {
return (
<>
<Wrapper>
<h1>react 高階組件</h1> {/* 添加模板內(nèi)容 */}
<TargetComponent />
</Wrapper>
</>
);
}
};
};
// 定義原始組件
class Test extends Component {
render() {
return (
<>
<div>
<div>hello world</div>
</div>
</>
);
}
}
// 使用高階組件包裝原始組件
export default CommonCssWrapper(Test);
五旗们、HOC 注意事項
1. 不能在無狀態(tài)組件(函數(shù)類型組件)上使用 ref 屬性
因為無狀態(tài)組件沒有實例
2. refs 屬性不能透傳
如果將 ref 添加到 HOC 的返回組件中,那么 ref 引用指向容器組件构灸,而不是被包裝的原始組件
4. 不要在 render 渲染方法中使用高階組件
因為每次 render 函數(shù)在執(zhí)行時上渴,都會卸載和重新加載高階組件,會造成狀態(tài)丟失
5. 靜態(tài)方法丟失
因為原始組件被包裹于一個容器組件內(nèi)喜颁,所以高階組件最終返回的組件沒有原始組件的靜態(tài)方法
但是可以通過 hoist-non-react-statics 腳本庫做處理稠氮,實現(xiàn)靜態(tài)方法拷貝
6. 不要以任何方式改變原始組件