高阶组件(Hoc)的几个应用

145 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情 

扩展功能,逻辑增强的思想在前端随处可见,webpack插件模式。Redux的插件模式都是这样,拦截处理增强处理功能,相当于流水线一样,可以在流水线中拦截做任意增强个性化操作。

高阶组件也是类似思想,对原始组件进行增强。 本文就几个例子来让我们更好的理解的运用高阶组件

添加footer

通常hoc都是以with开头的,所以我们写一个withFooter的高阶组件,目的是给包裹的组件添加Footer上去

import React from 'react';
function withFooter(Component) {

    Component.prototype.componentDidMount = function () {
        console.log('拦截componentDidMount方法,做一些操作')
        proDidMount.call(this)
    }

    return props => {
        return (
            <div style={Style.container}>
                <Component {...props} style={Style.content}/>
                <div style={Style.footer}>Footer部分</div>
            </div>
        )
    }
}

const Style = {
    container: {
        display: 'flex',
        flexDirection: 'column',
        height: '100%',
        width:'100%',
        background: '#00f'

},
    content: {
        flexGrow: 1,
        background: '#0ff',

    },
    footer : {
        display: 'flex',
        width:'100%',
        height:'200px',
        justifyContent: 'center',
        alignItems:'center',

        background: '#ff00ff',
    }
}
export default withFooter

对page页面包裹withFooter高阶组件

import React, { useLayoutEffect, useEffect, useState } from 'react';
import withFooter from "./withFooter";
function Page() {
    return <div style={{width:'100%', height:'100%'}}>
        我是Page页面
    </div>
}


export default withFooter(Page)

如果是class组件的话我们可以直接@withFooter即可实现相同功能。

@withFooter
class Page extend React.Component {

}

通过上述例子我们就可以知道高阶组件的巧妙之处,在不影响原组件的情况下,给原组件增强。

实现在onClick等逻辑代码中直接弹框

分析,要实现这个功能,相当于,首先让弹框组件Modal的visible永远为true 导出方法实例。当调用方法的时候,相当于将Modal加载到dom元素上去,点击取消,从dom上卸载

调用高阶组件方法的时候要

import {Modal} from 'antd'
import React from 'react'
import withDialog from "./withDialog";
import WithDialog from "./withDialog";
function ModalDialog(props) {
    const handleOk = () => {
        props.onOk(value)
        props.onCancel()
    }
    return (
        <Modal
            title={props?.title || '标题'}
            visible
            onCancel={props.onCancel}
            onOk={handleOk}
        >
            {props?.render() || null}
        </Modal>
    )

}

//关键导出一个方法。
export default () => new WithDialog(ModalDialog)


function Page(props) {
    const showDialog = () => {
        ModalDialog({
            onOk: () => {
                console.log('这里执行点击确认按钮的逻辑')
            },
            render: <div>我是弹框的content部分</div>
        })
    }

    return (
        <div onClick={showDialog}>弹框</div>
    )

}