看题目感觉好高级的样子,千万不要被名字吓到,它一点都不高深
按照惯例先上图,这一章的概览:

1.从高阶函数说起

维基百科对高阶函数的定义:

在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:

  • 接受一个或多个函数作为输入
  • 输出一个函数

是不是很简单?满足任一条件一句话说就是接受或者返回一个函数的函数就是高阶函数。
举个例子

        funA(){return funB(){};}

funA 就是一个高阶函数。
顺便提一下图上的高阶函数对应的三个实现,也是面试经常问道的,这里简单说一下。

1).函数回调

我们开发最长用的封装网络请求是一个高阶函数。

        function funRequest(params){return Http.post(params.URL,params.data);// 这里实际返回的是一个promise}

2).柯里化

是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术

其实就是 fun(a,b,c) -------柯里化-----> fun(a)(b)©;
举个例子:

    function add(a,b,c) {return (a + b + c);// 返回三个参数的和}// 把上述函数柯里化(这是一个简单实现,有兴趣的想想怎么实现任意个数的求和)function addH(a) {return function (b) {return function (c) {return (a + b + c);}}}console.log(add(1,2,3));console.log(addH(1)(2)(3));

3).函数节流

这个也不高深,就是平时我们页面加载过程中会有上拉频繁,加载数据会出现之前的请求还没有返回就又加载新的内容,不停的发送请求。这时我们就会进行节流。
伪代码:

       function request() {let start = true;return function (params) {if(start) {start = false;Http.post(params.URL, params.data).then(res => {start = true;})}}}let startRequest = request();if('触发请求'){startRequest({URL:'sslslssllsl',data:{}});}

2.高阶组件(order-hight-component)

高阶组件跟高阶函数极度相似,把函数的传入值和返回值从函数变成组件,那么这个函数就是高阶组件。
WrapperComponent参数是一个组件,那么下面函数HocComp1和HocComp2都是高阶组件

  const HocComp1 = WrapperComponent => class extends Component{// 继承Componentrender(){return (<div>HOC<WrapperComponent /></div>)}}
        const HocComp2 = WrapperComponent =>class extends WrapperComponent{// 继承的是传入的组件render(){const oldElements = super.render();return (<div>HOC{oldElements}</div>)}}

上面就是最简单的创建的两个高阶组件,功能是一样的在元组件的顶上加上“HOC”。

  • 继承Component的是属于属性代理方式创建的高阶组件
  • 继承传入组件的属于反向继承方式创建的高阶组件

1).属性代理

属性代理顾名思义,就是替代的意思高阶组件替传入组件管理控制props里面一切属性,管理控制包括增,删,改,查。同时他自身还有自身的状态,即state,来强化传入组件。打个比方,传入组件是画一个圆,其中只有一个props属性半径radius。那我们在高阶组件中就可以随意操作这个属性值,可大可小,还可以为props增加新的属性,比如增加一个color属性,表示圆的颜色;在组件外层加一个背景,美化传入组件。这个比方由大家去实现。
这里举一个稍微比这个难一点点的例子,受控的输入框。输入框组件的要求很简单,就是输入框中一直要有“输入:”这两个字和冒号。
分析:根据什么是受控组件,第一我们要通过state控制input的value属性。
第二我们要监控input输入值得变化,每当变化是我们拿到最新输入值,然后在前面拼接上“输入:”,设置一个state就可以了。所以需要onChange监听。
组件代码如下:

        class ControlInput extends Component{// 一个受控组件,通过属性代理的方式,把控制逻辑放进高阶组件中。render(){const { value , eventOnChange} = this.props;return (<input value={value} {...eventOnChange}/>)}}

注意这里没有任何逻辑,属性代理嘛,逻辑当然都在高阶组件中啦。
高阶组件如下:

import React,{ Component } from 'react';import '../../style/higherOrderComponent/higherOrderComponent.scss';const AttributeAgentHigherOrderComponent2 = (BaseComponent) =>class extends Component{constructor(props){super(props);this.state = {value:this.props.initValue || '',}}onValueChange = (event) => {let value = event.target.value.toString();// 这句最直观的体现什么是受控(要什么值显示什么值)value = `输入:${value === '输入' ? '' : value.replace('输入:','')}`;this.setState({value:value});}render(){const { value } = this.state;const newProps = {value: value,// input 的value属性eventOnChange:{onChange: this.onValueChange,// input的onChange监听,方法在高阶组件内},}const props = Object.assign({},this.props,newProps);// 合成最新的props传给传入组件return (<BaseComponent {...props}/>)}}export default AttributeAgentHigherOrderComponent2;

怎么用的呢,在导出ControlInput组件的地方调用即可

  export default AttributeAgentHigherOrderComponent2(ControlInput);

也可以使用ES6注解方式:

2).反向继承

属性代理方式在高阶组件中返回的组件继承的是Component,而反向继承则是继承的传入组件,根据继承的特性,继承可获取父类的所有静态资源,非私有属性和方法,且根据情况可对原方法进行重写。所以反向继承的方式也可以操作传入组件的props以及state。还有一个更重的就是反向继承可以进行渲染劫持

我们来句一个简单的例子,还是一个输入框,要求

  • 输入框中有值时就出现提交按钮,没有值时则消失。
  • 提交按钮可用
    按照组件开发,不用高阶组件完全可以写,还很简单。但是现在我们就用高阶组件写,看有什么区别。先写传入组件:
  class ReverseInput extends Component{constructor(props){super(props);this.state = {value:''}}// 处理提交动作。定义了方法没有方法实体toSubmit = () => {}// 处理输入值变化动作。定义了方法没有方法实体valueChange = (eve) => {}render(){const { value } = this.state;return (<div><input onChange={this.valueChange} value={value}/><button onClick={this.toSubmit}>提交</button></div>)}}

上面就是将要被继承的组件,里面有方法,但是却没有方法实体。这就是反向继承可以在高阶组件中进行方法的重写。注意组件中是有提交按钮的,我们要在高阶组件中进行控制显示和隐藏,使用的就是渲染劫持

const ReverseInherit1 = BaseComponent =>class extends BaseComponent{ // 继承传入组件// 在这里定义监听value值变化的函数valueChange = (eve) => {console.log(eve.target.value);this.setState({value:eve.target.value})}// 在这里重写提交的函数toSubmit = () => {alert(`您要提交的值是:${this.state.value}`);}render(){const { value } = this.state;const superEle =  super.render();// 拿到父组件的要渲染的结构对象,做渲染劫持的关键const newElement = React.cloneElement(superEle,this.props,superEle.props.children);if(value){// 如果value有值就不做任何处理返回父组件的renderreturn (super.render())}else{// value 有值则对原来的结构进行调整newElement.props.children.splice(1,1);return (newElement)}console.log(superEle);}}

用法跟上一个属性代理的一致。

是不是感觉高阶组件也不过如此?实际上难就难在去抽象组件逻辑,针对不同的需求。我门项目上就有一个问题比如权限相关的,所有组件中都有于某一权限相关的按钮或者其他内容,这些按钮和内容是和权限相关的,权限不足的人不能看到,如果每个人写组件的时候都在自己组件里判断,然后进行是否显示,这就造成一个问题,如果以后权限变动了,就要改很多处,这是比较麻烦的。但是高阶组件很好的解决了这个问题。只要在你写的组件中进行权限控制显示的内容上加一个标记,比如ref=‘xxxPower’等。我就可以让你组件通过我的高阶组件时对你的加了权限标记的内容进行显示和隐藏,所有组件都可以。

这个例子写在下面的工程源码里面了。运行后就是菜单 “HOC-反向继承2.1”.源码位置在powerButton文件夹
工程源码地址,点击这里

R6- React高阶组件详解相关推荐

  1. react高阶组件详解

    1 引言 高阶组件( higher-order component ,HOC )是 React 中复用组件逻辑的一种进阶技巧.它本身并不是 React 的 API,而是一种 React 组件的设计理念 ...

  2. react 高阶组件详解

    1.高阶组件是什么 高阶组件是一个函数,但 参数 和 返回值 为 组件. 高阶组件是包装了另外一个 React 组件的 React 组件.它可以大幅度的简化代码量.使我们更多的去复用代码: 高阶组件可 ...

  3. React的高阶组件详解

    文章目录 React的高阶组件 高阶组件基本介绍 高阶组件使用过程 高阶组件应用场景 高阶组件的意义 React的高阶组件 高阶组件基本介绍 什么是高阶组件呢? 在认识高阶组价之前, 我们先来回顾一下 ...

  4. react进阶系列 - 高阶组件详解四:高阶组件的嵌套使用

    前面有讲到过很多页面会在初始时验证登录状态与用户角色.我们可以使用高阶组件来封装这部分验证逻辑.封装好之后我们在使用的时候就可以如下: export default withRule(Home); 但 ...

  5. react高阶组件 事例 源码

    记录一下 高阶组件 的建立(也希望能帮助看的这篇文章的人),这篇文章主要是 教你构建一个hoc的事例,更详细深入的还是需要继续看其他文章 高阶组件通过包裹被传入的React组件,经过处理,最终返回(r ...

  6. React高阶组件_阶段1

    react高阶组件_阶段1 作用: 个人总结的高阶组件设计的作用主要有两点, 这里直接使用装饰器方式 非装饰器使用请结合我的博文"react基础梳理_阶段1"中的"自定义 ...

  7. react高阶组件和hooks

    1. react高阶组件 1.1 高阶组件的概念 高阶组件(Higher Order Component,简称:HOC ): 是 React 中用于重用组件逻辑的高级技术, 它本身不是react中的组 ...

  8. react实现汉堡_利用 React 高阶组件实现一个面包屑导航

    什么是 React 高阶组件 React 高阶组件就是以高阶函数的方式包裹需要修饰的 React 组件,并返回处理完成后的 React 组件.React 高阶组件在 React 生态中使用的非常频繁, ...

  9. [react] 高阶组件(HOC)有哪些优点和缺点?

    [react] 高阶组件(HOC)有哪些优点和缺点? HOC 优点 通过传递props去影响内层组件的状态,不直接改变内层组件的状态,降低了耦合度 缺点 组件多层嵌套, 增加复杂度与理解成本 ref隔 ...

最新文章

  1. ZLAN串口转接以太网ZLSN3003S
  2. Windows2003如何安装IIS
  3. DES对称加密(2)三重DES
  4. html鼠标标控制,html 鼠标 css 控制
  5. 《SAS编程与数据挖掘商业案例》学习笔记之一
  6. 论文浅尝 | 从树结构的长短期记忆网络改进语义表示
  7. 下面属于javascript内部对象的有_JavaScript从零开始——面向对象编程(2)
  8. 解决listview与scroll冲突,自定义listview高度
  9. 余弦相似度 高维数据_海量高维数据与近似最近邻
  10. mongodb维护常用命令
  11. Silverlight-Cailburn应用框架
  12. 在windows系统下安装linux双系统
  13. KindEditor上传图片
  14. pcie总线与cpci总线_PCI和CPCI
  15. php rabbitmq延迟队列实现
  16. VUE-amap遇到的坑和总结
  17. 一键查询 | 2020年最新SCI期刊影响因子报告
  18. 2022年海外有哪些直播带货平台?直播带货要怎么做?
  19. 5G网络能力开放部署及关键技术方案
  20. 容器编排之战——kubernetes

热门文章

  1. 免费1G全功能虚拟主机空间,稳定,能外链,不错
  2. 蓝牙耳机什么牌子的好又实惠?便宜又好用的蓝牙耳机推荐
  3. 数字芯片设计中常见的三个握手协议
  4. 前端的就业行情怎么样?
  5. pythonprint结果_Python语句print(type((1,2,3,4)))的输出结果是()
  6. C#与.NET 4高级程序设计:第5版
  7. MySQL 无法满足查询性能?北明天时选择 TDengine 实现热网监控和能源分析
  8. 创建Integration Services项目时,错误为0x8002801D 库没有注册
  9. windows系统经常卡死
  10. 刮刮乐,前端代码html+js实现,直接运行