一起来了解什么是 HOC
HOC
即Higher Order Component
,相信大家对这项技术并不陌生,但是真正用起来还是比较少的,起码我们项目是这样,用的最多的还是render props
。今天就带大家深入了解下HOC
,它究竟可以为我们带来什么。
起步
高阶组件(HOC
)是 React
中用于复用组件逻辑的一种高级技巧。HOC
自身不是 React API
的一部分,它是一种基于 React
的组合特性而形成的设计模式。具体而言,高阶组件是参数为组件,返回值为新组件的函数。
HOC
在 React
第三方库中很常见,比如 Redux
中 connect
。
const EnhancedComponent = higherOrderComponent(WrappedComponent);
1
高阶组件
我们都知道一个高阶组件,是通过把组件传到函数内,然后函数再返回一个组件的方式去做。在这里,我们传入 WrappedComponent
组件,然后再返回 WrapHOCComponent
组件。在方法内部,我们可以对传进来的 props
进行代理,也称属性代理 (props proxy
)。
function wrapHOC(WrappedComponent: React.ElementType) {
return class WrapHOCComponent extends Component {
render() {
return <WrappedComponent {...this.props} />;
}
};
}
export default wrapHOC;
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
属性代理
属性代理共有三种主要用途,操作 props
、访问组件实例和抽取公共属性与方法。
操作
props
,可以对prop
进行删除、新增、修改一系列操作。function wrapHOC(WrappedComponent: React.ElementType) { return class WrapHOCComponent extends Component { newProps = { wait: '小小' }; render() { return <WrappedComponent {...this.props} {...this.newProps} />; } }; }
1
2
3
4
5
6
7
8
9
10访问组件实例
function wrapHOC(WrappedComponent: React.ElementType) { return class WrapHOCComponent extends Component { newProps = { wait: '小小' }; wrappedComponentRef = Object.create(null); render() { return ( <WrappedComponent ref={(node: object) => (this.wrappedComponentRef = node)} {...this.props} {...this.newProps} /> ); } }; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17抽取公共属性与方法。比如我们每一个组件有相同的数据格式和绑定一个点击事件,那我们就可以在高阶组件内去写这一段逻辑,而不必每一个组件内部都实现一遍。
function wrapHOC(WrappedComponent: React.ElementType, params: IParams) { return class WrapHOCComponent extends Component<IWrapHOCComponentProps, IWrapHOCComponentState> { constructor(props: IWrapHOCComponentProps) { super(props); this.state = params; this.handleClick = this.handleClick.bind(this); } wrappedComponentRef = Object.create(null); handleClick() { console.log(this.state.name); } render() { return ( <WrappedComponent onClick={this.handleClick} ref={(node: object) => (this.wrappedComponentRef = node)} {...this.state} /> ); } }; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22