前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React 高阶HOC (一)

React 高阶HOC (一)

原创
作者头像
ronixiao
修改2022-08-08 13:01:19
8180
修改2022-08-08 13:01:19
举报
文章被收录于专栏:小程序深入小程序深入

高阶组件

高阶组件 (HOC) 是 React 中用于重用组件逻辑的高级技术。HOC 本身并不是 React API 的一部分。它们是从 React 的组合性质中出现的一种模式。

高阶组件定义

根据官网介绍

高阶组件是一个接受一个组件并返回一个新的函数

代码语言:javascript
复制
const myComponent = HOC(subComponent)

存在两个逻辑相似,页面功能相似的页面,可以使用高阶函数去减少相同相似的代码,共享方法,和生命周期钩子函数

用法与注意事项(官网):

1.高阶组件是参数为组件,返回值为新组件的函数。 2.HOC 不会修改传入的组件,也不会使用继承来复制其行为。相反,HOC 通过将组件包装在容器组件中来组成新组件,HOC 是纯函数,没有副作用。 3.不要试图在 HOC 中修改组件原型 4.HOC 通常可以接收多个参数 4.不要在 render 方法中使用 HOC 5.务必复制静态方法 6.Refs 不会被传递,可使用React.forwardRef 解决

使用格式:

一般文件和方法名都是with开头


包装组件

普通包装

export 暴露
代码语言:javascript
复制
import React, { Component } from 'react'

export default Class Wrap extends Component {
    render() {
        return (
            <div>{ this.props.name }</div>
        )
    }
}
import 包装
代码语言:javascript
复制
 import Wrap from './Wrap';
 import withContainer from './HOC/withContainer'

 const userContainer = withContainer(Wrap);
 const userPage = () => {
     return (
        <div>
            <userContainer name={'BobMary'} />
        </div>
     )
 }
 

装饰器包装(只存在类class用法中)

代码语言:javascript
复制
import React, { Component } from 'react'
import withContainer from './HOC/withContainer'

@withContainer
export default class Wrap extends Component {
     render() {
        return (
            <div>{ this.props.name }</div>
        )
    }
}

项目举例

项目需求

某个公司需要搬迁,需要系统采集登记已经搬迁的信息,包括:人员,物品,车辆。从A地区 搬迁到B地区。

需求分析

需要多个文件,实现的方式方法类似,展示的内容稍微不同,如果单独写每个文件,冗余代码较多,维护不便。

如果编写如下的代码,实现单个模块的逻辑,如果存在更细致的统计,那将复制粘贴出大量的相识相同的代码。

在假如,在搬迁的时候要求增加是谁负责某个模块,需要签名并实现流程化,那么这么多的模块都单独在增加,维护量和阅读量都非常的大

拓展( 应用场景)

  • 1 路由配置:对路由进行封装,针对复杂树形导航与头部导航交替路由;也用于未登录未授权的用户的拦截
  • 2 数据监控:加入埋点,分析数据
  • 3 数据校验:表单的统一校验
  • 4 数据异常处理:对报错数据进行处理,可以使用弹框提示,也可以进入埋点
  • 5 权限判断:类似路由,点击按钮时,对页面的权限进行验证,在返回对应的路由或者弹框
代码语言:javascript
复制
// bad
import React, { Component} from 'react'
class GetGoodList extends Component {
    constructor() {
        this.state = {
            ...
        }
    }

    handleChangeCheck(e, index, id) {
       ...
    }

    handleMoveSome() {
        ...
    }

    render() {
        const { xxx } = this.state
        return (
            ...
            <span>car</span>
        )
    }
}
export default GetGoodList

如果要从人员,物品,车辆,分成三个文件独立维护,需要写大量重复的代码,因从我们需要将大部分逻辑代码提出来

HOC写法例子如下:

效果图:

代码语言:javascript
复制
import React, { Component } from 'react'
import SuperList from '../components/list/SuperLIst'

function withMove (WrapComponent, preData) {
    return class MoveSomeToPlace extends Component {
        constructor(props) {
            super(props)
            this.needMoves = []
            this.state = { ...preData, hasMoved: []}
        }
    
        handleChangeCheck() {
            return (e, index, id) => {
                const { checked } = e.target
                const { userListShow } = this.state
                const position = this.needMoves.findIndex(e => e.id == id) 
                const isExist = position === -1
                if (checked &amp;&amp; isExist) {
                    this.needMoves.push(userListShow[index])
                } else if (!checked &amp;&amp; !isExist) {
                    this.needMoves.splice(position, 1)
                }
                userListShow[index].hasChecked = checked ? 'checked' : ''
                this.setState({
                    userListShow
                })
            }
          
        }
    
        handleMoveSome() {
            const data = [ ...this.needMoves ]
            this.setState({
                hasMoved: data
            })
        }
    
        render() {
            const { moveType, userListShow, hasMoved } = this.state
            return (
                <div className="c-stop-area">
                    <div className="need-move--left">
                        <SuperList lists={userListShow} needCheckbox
                            handleChangeCheck={this.handleChangeCheck()} />
                    </div>
                    <div>
                        <button className="c-btn" onClick={() => this.handleMoveSome()}>{moveType}</button>
                    </div>
                    <div className="has-moved--right">
                        <SuperList lists={hasMoved}
                            handleChangeCheck={this.handleChangeCheck()} />
                    </div>
                    <WrapComponent {...this.props}/>
                </div>
            )
        }
    }
}

export default withMove

三个不同的文件 ,数据和组件与之不同,但是完成的事相同,都是将A(左侧区域)的物品或人员通过勾选,入栈,在点击中间按钮进行移动(拷贝操作)最后呈现到B(右侧区域)

代码语言:javascript
复制
// 物品 搬运,数据列表不同
import React, { Component} from 'react'
import goodList from '../../mock/good'
import withMove from '../../HOC/withMove'

const goodSource = {
    moveType: '搬运',
    userListShow: goodList
}
class GetGoodList extends Component {
    render() {
        return (<span>good</span>)
    }
}
export default withMove(GetGoodList, goodSource)

//=================================

// 人员 移动,数据列表不同
import React, { Component} from 'react'
import userList from '../../mock/user'
import withMove from '../../HOC/withMove'

const userSource = {
    moveType: '移动',
    userListShow: userList
}
class GetUserList extends Component {
    render() {
        return (<span>user</span>)
    }
}

export default withMove(GetUserList, userSource)

//=================================

// 汽车 启动,数据列表不同
import React, { Component } from 'react'
import carList from '../../mock/car'
import withMove from '../../HOC/withMove'

const carSource = {
    moveType: '启动',
    userListShow: carList
}

class GetCarList extends Component {
    render() {
        return (<span>car</span>)
    }
}

export default withMove(GetCarList, carSource)

持续更新,反向继承例子 与 ref使用

写的比较简单,有不足处,需要补充的地方欢迎大家留言,相互学习

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 高阶组件
    • 高阶组件定义
      • 包装组件
        • 普通包装
        • 装饰器包装(只存在类class用法中)
      • 项目举例
        • 项目需求
        • 需求分析
        • 拓展( 应用场景)
    • 写的比较简单,有不足处,需要补充的地方欢迎大家留言,相互学习
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
    http://www.vxiaotou.com