React High-Order-Component (HOC)高阶组件入手

本文介绍了React高阶组件(HOC)的概念,它是一种用于复用组件逻辑的高级技巧,不是React API的一部分。文章讨论了为何使用HOC,包括减少重复实现相同功能的目的。接着详细讲解了代理式和继承式的HOC用法,特别提到了代理式HOC的两种写法。此外,还介绍了如何在create-react-app项目中启用装饰器模式,包括安装和配置过程。最后,阐述了HOC的功能,如操纵props和访问ref。
摘要由CSDN通过智能技术生成

react中文网上这样定义高阶组件:
高阶组件(HOC) 是React中用于复用组件逻辑的一种高级技巧。HOC自身不是React API的一部分, 它是一种基于React的组合特性而形成的设计模式。

综上所述:

1)高阶组件 接受一个组件作为参数, 并返回一个新组件的方法;

2)高阶组件 是一个函数, 不是组件。

为什么使用高阶组件?
当多个组件都需要某个相同的功能, 使用高阶组件可以减少重复实现。

高阶组件的使用
高阶组件分为代理式 和继承式。

代理式组件:返回的组件是继承的React.Component类。被传入的组件(也叫被包裹的组件)将会在返回的新组件的render()方法中渲染出来。

继承式组件: 返回的组件是继承的是被传入的组件类。

import React, { Component } from "react";

export default ( args )=>( WrappedComponent )=>class NewComponent extends WrappedComponent{
        constructor(props){
            super(props);
        }
        
        render () {
            return super.render();
        }
    }
}
(由于不推荐使用继承式组件, 所以不在讲述)

代理式组件的用法:

第一种写法:(无其他参数)

此方式的高阶组件(hoc)的入参 是一个组件, 但此方式不可以有其他的参数。

import React, { Component  } from "react";

function hoc ( WrappedComponent ) {
    return class NewComponent extends Component{
        constructor(props){
            super(props);
        }
        
        render () {
            return (
                <WrappedComponent/>
            )
        }
    }
}

那么在当作参数传入到高阶组件的入参组件,是如何使用高阶组件的呢?

这里会介绍两种使用高阶组件的方式, 二者只能选其一。

import React, { Component } from "react";
import hoc from "./hoc"; //引入高阶组件。找到正确的文件路径

class WrappedComponent extends Component{    
    constructor(props){
         super(props);
    }
        
    render () {
       return (
          <div>我不是高阶组件, 我是高阶组件的传入组件。很普通的哦!</div>
       )
   }
}
export default hoc(WrappedComponent); //这是第一种,此种方法类似函数的调用
import React, { Component } from "react";
import hoc from "./hoc"; //引入高阶组件。找到正确的文件路径

@hoc //这是第二种,react中叫做装饰器,java中叫做注解。在使用这种时, 还要使用正确的babel插件,后续介绍
class WrappedComponent extends Component{    
    constructor(props){
         super(props);
    }
        
    render () {
       return (
          <div>我不是高阶组件, 我是高阶组件的传入组件。很普通的哦!</div>
       )
   }
}

export default WrappedComponent;

第二种写法:(可以有其他参数)
此方式的高阶组件(hoc)的入参 是一个组件, 但此方式还可以有其他参数传入高阶组件中。

import React, { Component } from "react";

export default ( args )=>( WrappedComponent )=>class NewComponent extends Component{
        constructor(props){
            super(props);
        }
        
        render () {
            return (
                <WrappedComponent />
            )
        }
    }
}

那么在当作参数传入到高阶组件的入参组件,是如何使用高阶组件的呢?

这里会介绍两种使用高阶组件的方式, 二者只能选其一。

import React, { Component } from "react";
import hoc from "./hoc"; //引入高阶组件。找到正确的文件路径

class WrappedComponent extends Component{    
    constructor(props){
         super(props);
    }
        
    render () {
       return (
          <div>我不是高阶组件, 我是高阶组件的传入组件。很普通的哦!</div>
       )
   }
}
export default hoc()(WrappedComponent); //这是第一种,此种方法类似函数的调用 、

//注意这里的hoc调用方法,与第一种写法(无其它参数)调用方法不一样。
//无其它参数 hoc(WrappedComponent)
//有其他参数 hoc()(WrappedComponent)
import React, { Component } from "react";
import hoc from "./hoc"; //引入高阶组件。找到正确的文件路径

//注意这里的hoc调用方法,与第一种写法(无其它参数)调用方法不一样。
//无其它参数 @hoc
//有其他参数 @hoc()

@hoc() //这是第二种,react中叫做装饰器,java中叫做注解。在使用这种时, 还要使用正确的babel插件,后续介绍
class WrappedComponent extends Component{    
    constructor(props){
         super(props);
    }
        
    render () {
       return (
          <div>我不是高阶组件, 我是高阶组件的传入组件。很普通的哦!</div>
       )
   }
}

export default WrappedComponent;

装饰器(主要讲述安装到项目中, 举例以create-react-app创建)
略定义: 装饰器是一个函数, 用@标识。可以使用在类上或者函数上。

开始讲述安装方案:

使用create-react-app创建的项目本身是不支持装饰器模式的。所以需要自己去依赖装饰器插件。

1.先安装create-react-app脚手架

npm install -g create-react-app

在这里插入图片描述
此时安装脚手架成功。

2.使用脚手架创建新的项目

create-react-app yourProjectName

如果此时报了在这里插入图片描述
就使用

npx create-react-app yourProjectName

在这里插入图片描述
此时项目创建成功。

3.创建完成后,进入项目

找到根目录下的package.json文件

在终端执行下列语句

npm run eject

在这里插入图片描述
会输出are you want to eject ?y/n 选择y就可以了
在这里插入图片描述
然后会下载各种依赖,并会更新package.json里的内容。

截至到此如果运行npm run eject时,报错。则试着先输入以下命令

git add.
git commit -m "init"

后在执行一次

npm run eject

4.在package.json中添加如下语句:

  "babel": {   
     "plugins": [      
          [       
             "@babel/plugin-proposal-decorators",        
             {          "legacy": true        }      
          ]    
      ],    
      "presets": [      "react-app"    ]  
  },

并下载@babel/plugin-proposal-decorators;如果失败,大多数原因是版本的原因。可自行在网络中查询对应的版本号。

到此为止, 装饰器就可以正常使用了。

5.如果不想在package.json中使用babel去处理装饰器,也可以选择在根目录创建.babelrc文件。在.babelrc文件中语句的模式与上边在package.json中类似。这里不再讲述,可以百度哟。

6.注意,package.json的babel与.babelrc文件二者选其一。

代理式模式高阶组件的功能
1.操纵props

高阶组件通过在自身处理props,再将处理好的props,传给传入组件,从而操纵传入组件的props。

import React, { Component } from "react";

export default ( args )=>( WrappedComponent )=>class NewComponent extends Component{
        constructor(props){
            super(props);
        }
        
        render () {
            const {name, otherProps} = this.props;//将不想传入给WrappedComponent组件的props过滤出来。
            
            return (
                <div>                      
                {/** 在WrappedComponent组件中, 就可以获取并使用高阶组件中的props了*/}                  
                 <WrappedComponent {...otherProps}/>
                </div>
            )
        }
    }
}

2.访问ref (ref不会被传递, 但可以访问)

import React, { Component } from "react";

export default ( args )=>( WrappedComponent )=>class NewComponent extends Component{
        constructor(props){
            super(props);
        }

        refs = (instance) => {
            console.log(instance)//这里访问的是传入组件WrappedComponent的实例。这样就可以在高阶组件中,使用WrappedComponent的实例了。
        }

        render () {
            const {name, otherProps} = this.props;//将不想传入给WrappedComponent组件的props过滤出来。
            
            return (
                <div>      
                    <WrappedComponent ref = {this.refs}/>
                </div>
            )
        }
    }
}

代码是在这里纯手写, 可能会到编辑器上有些许的书写错误, 但,基本上完全可以拿去用。

                                                               		 -----希望有理解的不对的地方, 还要多多指出。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值