一起来了解什么是 HOC

HOCHigher Order Component,相信大家对这项技术并不陌生,但是真正用起来还是比较少的,起码我们项目是这样,用的最多的还是 render props。今天就带大家深入了解下 HOC,它究竟可以为我们带来什么。

起步

高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。具体而言,高阶组件是参数为组件,返回值为新组件的函数。 HOCReact 第三方库中很常见,比如 Reduxconnect

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

属性代理

属性代理共有三种主要用途,操作 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

参考文档

最后更新: 8/19/2019, 8:22:29 PM