iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >ReactHOC高阶组件深入讲解
  • 646
分享到

ReactHOC高阶组件深入讲解

ReactHOCReact高阶组件 2022-11-13 18:11:45 646人浏览 泡泡鱼
摘要

目录1. 概念2. 属性代理2.1 代理props2.2 条件渲染2.3 添加状态3. 反向继承3.1 拦截渲染3.2 劫持生命周期3.3 操作state3.4 修改React树3.

1. 概念

高阶组件和高阶函数的类似,使用函数接收一个组件,并返回一个组件。

function withList(WrapComponent) {
  return class extends Component {
    render() {
      return <div><WrapComponent {...this.props}/></div>;
    }
  }
};

高阶组件主要用作于逻辑的封装、拦截渲染、拦截生命周期:获取渲染性能,日志打点等,安按照实现方式可以分为属性代理和反向继承两种。

2. 属性代理

属性代理的作用:

  • 代理props
  • 条件渲染
  • 添加状态(state)
  • 封装一些通用的逻辑

2.1 代理props

function withList(WrapComponent) {
  const data = [{ id: '1', text: '测试1' }, { id: '2', text: '测试2' }, { id: '3', text: '测试3' }, { id: '4', text: '测试4' }, { id: '5', text: '测试5' }]
  return class extends Component {
    render() {
      return <div>
        {this.props.data.length > 0 ? <WrapComponent {...this.props} data={data} /> : <span>{emptyText}</span>}
      </div>;
    }
  }
};
class List extends Component {
  render() {
    return (
      <ul>
        {this.props.data.map(item => {
          return <li key={item.id}>{item.text}</li>
        })}
      </ul>
    )
  }
};
export default withList(List);

2.2 条件渲染

function withList(WrapComponent, emptyText) {
  return class extends Component {
    render() {
      return <div>
        {this.props.data.length>0 ? <WrapComponent {...this.props}/> : <span>{emptyText}</span>}
      </div>;
    }
  }
};
 class List extends Component {
  render() {
    return (
      <ul>
        {this.props.data.map(item => {
          return <li key={item.id}>{item.text}</li>
        })}
      </ul>
    )
  }
};
export default withList(List,'暂无数据');

2.3 添加状态

利用这一点可以将非受控组件转为受控组件

import React, { Component } from 'react'
class Input extends Component {
  render() {
    return (
      <input value={this.props.value} />
    )
  }
};
function withInput(WrapComponent) {
  return class extends Component {
    state = {
      value: this.props.value
    }
    onChange = (value) => {
      this.setState({ value });
    }
    render() {
      return <WrapComponent {...this.props} value={this.state.value} onChange={this.onChange}/>;
    }
  }
};
export default withInput(Input);

3. 反向继承

  • 反向继承的作用
  • 拦截渲染
  • 代理props
  • 劫持生命周期函数
  • 操作state
  • 修改react树

3.1 拦截渲染

function withList(WrapComponent) {
  return class extends WrapComponent {
    render() {
      return <div>
        <span>通过反向继承拦截渲染</span>
        {super.render()}
      </div>;
    }
  }
};

3.2 劫持生命周期

function withList(WrapComponent) {
  return class extends WrapComponent {
    componentDidMount(){
      if(super.componentDidMount){
        super.componentDidMount.apply(this);
      };
      console.log('拦截生命周期');
    }
    render() {
      return <div>
        <span>通过反向继承拦截渲染</span>
        {super.render()}
      </div>;
    }
  }
};

3.3 操作state

import React, { Component } from 'react';
function withList(WrapComponent) {
  return class extends WrapComponent {
    constructor(props) {
      super(props);
      this.state.data = []; //将列表数据置空
    }
    render() {
      return <div>{super.render()}</div>
    }
  }
};
class List extends Component {
  state = {
    data: [{ id: '1', text: '测试1' }, { id: '2', text: '测试2' }, { id: '3', text: '测试3' }, { id: '4', text: '测试4' }, { id: '5', text: '测试5' }],
  }
  render() {
    return (
      <ul>
        {this.state.data.map(item => {
          return <li key={item.id}>{item.text}</li>
        })}
      </ul>
    )
  }
};
export default withList(List);

3.4 修改react树

import React, { Component } from 'react';
function withList(WrapComponent) {
  return class extends WrapComponent {
    render() {
      const tree = super.render();
      let newProps = { ...tree.props };
      if (tree.type === 'ul') {
        newProps.value = 'value';
      }
      return React.cloneElement(tree, newProps, newProps.children);
    }
  }
};
class List extends Component {
  render() {
    return (
      <ul>
        {this.props.data.map(item => {
          return <li key={item.id}>{item.text}</li>
        })}
      </ul>
    )
  }
};
export default withList(List);

3.5 记录渲染性能

function withTime(WrapComponent) {
  return class extends WrapComponent {
    constructor(props) {
      super(props);
      this.start = 0;
      this.end = 0
    }
    componentWillMount() {
      if (super.componentWillMount) {
        super.componentWillMount.call(this);
      };
      this.start = Date.now();
    }
    componentDidMount() {
      if (super.componentDidMount) {
        super.componentDidMount.call(this);
      };
      this.end = Date.now();
      console.log(`渲染的时间为:${(this.end - this.start) / 1000}秒`)
    }
    render() {
      return super.render();
    }
  }
};

4. 使用装饰器

4.1 安装和配置

首先执行npm run eject暴露出webpack配置,然后安装装饰器插件

yarn add  @babel/plugin-proposal-decoreators;

最后在package.JSON中的babel配置中添加一下配置然后重新项目

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

配置完之后如果有报红需要配置一下:

文件-> 首选项 -> 搜索 ExperimentalDecorators 勾选上之后红线就消失了

4.2 使用

@withList
class List extends Component {
  render() {
    return (
      <ul>
        {this.props.data.map(item => {
          return <li key={item.id}>{item.text}</li>
        })}
      </ul>
    )
  }
};

5.总结

  • 高阶组件的作用有代复用、代理属性、拦截渲染、劫持生命周期
  • 反向继承能直接操作和拦截组件的state和生命周期,功能比属性代理更加强大

到此这篇关于React HOC高阶组件深入讲解的文章就介绍到这了,更多相关React HOC 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: ReactHOC高阶组件深入讲解

本文链接: https://www.lsjlt.com/news/169368.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • ReactHOC高阶组件深入讲解
    目录1. 概念2. 属性代理2.1 代理props2.2 条件渲染2.3 添加状态3. 反向继承3.1 拦截渲染3.2 劫持生命周期3.3 操作state3.4 修改react树3....
    99+
    2022-11-13
    React HOC React 高阶组件
  • React受控组件与非受控组件深入讲解
    目录一、非受控组件二、受控组件三、高阶函数(函数柯里化)实现1、定义2、实现四、不用函数柯里化的实现一、非受控组件 表单中输入类DOM的值现用现取 <script type="...
    99+
    2022-12-26
    React受控组件 React非受控组件
  • vue3单文件组件中style特性的深入讲解
    目录style scopedstyle module状态驱动的动态css总结style scoped 需要注意的有: 样式不会影响到其他组件,只会在当前组件生效。 ...
    99+
    2022-11-12
  • vue3组件中v-model的使用以及深入讲解
    目录v-model input中使用双向绑定数据 组件中的v-model 其他写法 总结v-model input中使用双向绑定数据 v-model在vue中我们经常用它与inpu...
    99+
    2022-11-12
  • PHP之深入学习Yii2缓存Cache组件详细讲解
    什么是缓存组件Cache 缓存是提升 Web 应用性能简便有效的方式。 通过将相对静态的数据存储到缓存并在收到请求时取回缓存, 应用程序便节省了每次重新生成这些数据所需的时间。 定...
    99+
    2022-11-12
  • Vue中父子组件通信与事件触发的深入讲解
    目录一、组件子组件父组件二、父子组件通信父组件给子组件通信子组件向父组件通信三、父子组件事件触发父组件调用子组件中的事件方法子组件调用父组件中的事件方法四、总结一、组件 子组件 &l...
    99+
    2022-11-13
  • Python字典高级用法深入分析讲解
    目录一、 collections 中 defaultdict 的使用1.字典的键映射多个值2.统计字典中某个值出现的次数二、collections 创建有序字典1.改变 key-va...
    99+
    2022-11-11
  • 深入了解python高阶函数编写与使用
    目录1.变量可以指向函数2.函数名也可以是变量。3.传入函数总结何为高阶函数,以实际代码为例子一步步深入概念。 1.变量可以指向函数 以abs()为例: >>>...
    99+
    2022-11-12
  • python中列表(list)和元组(tuple)的深入讲解
    前言 在我们实际开发中,经常需要将一组数据存储起来,以便使用。如果学习了其他的语言可能知道数组(Array)这个数据结构,它就可以将多个数据进行存储,访问数据可以通过数组下标的方式...
    99+
    2022-11-11
  • 深入讲解Java的对象头与对象组成
    目录一,对象头1,Mark Word2,指向类的指针3,数组长度二,实例数据三,对齐填充字节总结Java对象保存在内存中时,由以下三部分组成: 1,对象头 2,实例数据 3,对齐填充...
    99+
    2022-11-13
  • Node异步和事件循环的深入讲解
    目录前言为什么要异步?如何实现异步?基于事件循环的异步编程模型timerspendingidle、preparepollcheckclose一些注意事项总结参考资料前言 Node 最...
    99+
    2022-11-13
  • 深入解析Android中的RecyclerView组件
    前些日子,组里为了在目前的Android程序里实现基于ListView子项的动画效果,希望将最新的RecyclerView引入到程序中,于是我便花了一些时间研究了一下Recyc...
    99+
    2022-06-06
    recyclerview Android
  • C语言深入讲解条件编译的用处
    目录一、基本概念二、条件编译的本质三、#include 的本质四、条件编译的意义五、小结一、基本概念 条件编译的行为类似于 C 语言中的 if...else...编译是预编译指示命令...
    99+
    2022-11-13
  • Java深入讲解AWT实现事件处理流程
    目录AWT的事件处理AWT中的事件继承图事件适配器小结AWT的事件处理 事件处理主要是为了响应用户的操作 事件对象(Event):封装了GUI组件上发生的特定事件(通常就是用户的一次...
    99+
    2022-11-13
  • SpringMVC深入讲解文件的上传下载实现
    目录SpringMVC文件下载SpringMVC文件上传1.基本介绍2.需求分析/图解3.应用实例4.Debug-file.transferTo(目标文件)SpringMVC文件下载...
    99+
    2022-11-13
  • Java设计模式之单件模式深入讲解
    目录定义Java单件模式经典单件模式的实现多线程单件模式的实现急切创建实例双重检查加锁Python单件模式模块实现new关键字实现装饰器实现函数装饰器类装饰器定义 单件模式确保一个类...
    99+
    2022-11-12
  • AndroidView的事件分发机制深入分析讲解
    目录1.分发对象-MotionEvent2.如何传递事件1.传递流程2.事件分发的源码解析1.Activity对点击事件的分发过程2.顶级View对点击事件的分发过程3.主要方法4....
    99+
    2023-01-29
    Android View事件分发机制 Android事件分发
  • 深入了解Vue3组件传值方式
    目录父子组件传值 props祖孙组件传值 provide 和 inject父组件中点击按钮向子组件传值今天说一下 vue3 的组件间传值,学习过 vue2 的宝子们肯定知道,组件传值...
    99+
    2022-11-13
  • 深入了解Vue中的动态组件
    1、什么是动态组件动态组件指的是动态切换组件的显示与隐藏。(学习视频分享:vue视频教程)2、如何实现动态组件渲染vue 提供了一个内置的 <component> 组件,专门用来实现动态组件的渲染。示例代码如下:3、使用 kee...
    99+
    2022-11-22
    Vue
  • React组件化学习入门教程讲解
    目录模块化模块模块化组件化组件组件化函数式组件创建函数组件Props参数传递(重点)复合函数组件类式组件创建实例用户自定义组件模块化 模块 理解:向外提供特定功能的js程序,一般就是...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作