React的高阶组件

134 阅读2分钟

定义

官方定义:

高阶组件(HOC)是React中用于复用组件逻辑的一种高级技巧。HOC自身不是React API的一部分,它是一种基于React的组合特征

具体而言,高阶组件是参数为组件,返回值为新组件的函数。

const EnhancedComponent = higherOrderComponent(WrappedComponent);

我们可以进行如下的解析:

  • 首先,高阶组件本身不是一个组件,而是一个函数;
  • 其次,这个函数的参数是一个组件,返回值也是一个组件。

高阶组件的编写过程类似于这样:

function higherOrderComponent(WrapperComponent){
    class NewComponent extends PureComponent {
        render() {
            return <WrapperComponent/>
        }
    }
    NewComponent.displayName = 'kobe';
    return NewComponent;
}

组件的名称问题:

  • 在ES6中,类表达式中类名是可以省略的;
  • 组件的名称都可以通过displayName来修改;

下面看几个高阶函数的应用:

应用一 - props的增强

  • 不修改原有代码的情况下,添加新的props

    function enhanceProps(WrapperCpn, otherProps) {
        return (props) => <WrapperCpn {...props} {...otherProps}/>
    }
    
  • 利用高阶组件来共享Context

    function withUser(WrapperCpn) {
        return props => {
            return (
                <UserContext.Consumer>
                    {
                        value => {
                            return <WrapperCpn {...props} {...value}>
                        }
                    }
                
                </UserContext.Consumer>
            )
        }
    }
    

应用二 - 渲染判断鉴权

  • 在开发中,我们可能遇到这样的场景:

    • 某些页面是必须用户登录成功才能进行进入;
    • 如果用户没有登录成功,那么直接跳转到登录页面;
  • 这个时候,我们就可以使用高阶组件来完成鉴权操作:

    function loginAuth(Page) {
        return props => {
            if(props.isLogin) {
                return <Page/>
            }else {
                return <LoginPage/>
            }
        }
    }
    

应用三 - 生命周期劫持

  • 我们也可以利用高阶组件来劫持生命周期,在生命周期中完成自己的逻辑:

    function logRenderTime(WrapperCpn) {
        return class extends PureComponent {
            UNSAFE_componentWillMount() {
                this.begin = Date.now();
            }
            
            componentDidMount() {
                this.end = Date.now();
                const interval = this.end - this.begin;
                console.log(`${WrapperCpn.name}渲染使用时间:${interval}`);
            }
            render() {
                return <WrapperCpn {...this.props}>
            }
        }
    }
    

高阶组件的意义

  • 我们会发现利用高阶组件可以针对某些React代码进行更加优雅的处理。

  • 其实早期的React有提供组件之间的一种复用方式是mixin,目前已经不再使用

    • mixin可能会相互依赖,相互耦合,不利于代码维护。会增加代码的复杂性。
  • 当然HOC也有自己的一些缺陷:

    • HOC需要在原组件上进行包裹或者嵌套,如果大量使用HOC,将会产生非常多的嵌套,这让调试变得非常困难。