关于 Decorator 到底是 ES 6 引入的还是 ES 7 引入的我也不是很明白了,两种说法都有,这种问题懒得纠结了……在用的时候发现这个东西很好用,平常用处可能不大,但是结合 React 就很好使了。接下来就讲一讲。

一、环境搭建

我搭建了一个 React 开发环境,结合 babel 的插件——babel-plugin-transform-decorators-legacy一起使用,这个插件可以让你写 Decorator。

GitHub 地址:https://github.com/zhongdeming428/HOC

可以通过如下命令克隆:

$ git clone https://github.com/zhongdeming428/HOC.git

克隆下来以后就可以尝试啦!

二、Decorator 的基本使用

装饰器本身就是一个函数,使用起来挺简单,无非就是修饰类或者类的函数。使用 @ 调用,扔在要修饰的类或者类方法前面就可以了。但是在修饰类和类函数的时候又有细微的差异。

class A {
@sayB
sayA() {
console.log('a');
}
}
function sayB(target, name, descriptor) {
// ...
}

在使用装饰器装饰类函数的时候,可以接受三个参数。第一个是要修饰的对象,第二个是修饰的属性名,第三个是属性描述符。可以在我搭建的项目中进行尝试。

在用装饰器装饰类的时候,只能够接受一个参数——target。这区别于上面的情况:

@APlus
class A { }
function APlus(target, name, descriptor) {
// ... 打印一下可以发现 name、descriptor 是 undefined。
}

另外,装饰器还可以接受参数,返回一个符合装饰器规范的新函数即可,这样又可以对装饰器的装饰行为进行定制了。比如:

@attach2Prop({ name: 'A' })
class A { } @attach2Prop({ name: 'B' })
class B { } function attach2Prop(obj) {
return function(target) {
target.prototype.$data = obj;
}
} console.log((new A()).$data.name);
console.log((new B()).$data.name);

结果会输出 AB

这就就可以用同一个装饰器实现不同行为的装饰了。

那么结合 React 有什么妙用呢?

三、结合 React 使用

(1)简化 React-Redux 的使用

以往在使用 react-redux 时,在定义好 UI 组件后,还要定义容器组件:

class UIComponent extends React.Component {

}

const ContainerComponent = connect(mapState2Props, mapDispatch2Props)(UIComponent);

export default ContainerComponent;

有了装饰器之后:

@connect(mapState2Props, mapDispatch2Props)
class UIComponent extends React.Component { } export default UIComponent;

这样用简化的代码达到了同样的效果,还省去了给容器组件命名的麻烦……代码也更加的整洁。

(2)定制高阶组件

上一小节中的容器组件实际上就是一个高阶组件,但是我们自己有时候也要定义一些高阶组件,实现代码的更高层次的复用。

例如:我们做了一个组件库,里面有一部分的组件是有一个功能特征的,那就是可以拖拽;又比如我们做的移动端组件,需要实现一个左滑删除功能。我们需要给每种具有这个特征的组件写一遍拖拽或者左滑删除逻辑吗?

显然是否定的,我们可以实现一个纯逻辑组件,而非 UI 组件,它的功能就是使得你的 UI 组件具有某种特定功能。比如上面提到的左滑删除或者拖拽。

这个纯逻辑组件就可以是一个装饰器,是一个高阶组件。

在我搭建的开发环境中,就实现了这样一个简单的高阶组件,让你的 UI 组件在鼠标滑入时显示为一只手。

装饰器代码如下:

// src/decorators/CursorPointer.js
import React from 'react'; export default Component => class extends React.Component {
render() {
return <div style={{cursor: 'pointer', display: 'inline-block'}}>
<Component/>
</div>
}
}

这个装饰器(高阶组件)接受一个 React 组件作为参数,然后返回一个新的 React 组件。实现很简单,就是包裹了一层 div,添加了一个 style,就这么简单。以后所有被它装饰的组件都会具有这个特征。

使用这个装饰器:

import React from 'react';
import Clickable from '../decorators/CursorPointer'; @Clickable
class ClickablePanel extends React.Component {
render() {
return <div className="panel"> </div>
}
} export default ClickablePanel;

将装饰器与高阶组件相结合,可以大大优化你的 React 代码!

ES 6 装饰器与 React 高阶组件的更多相关文章

  1. 函数式编程与React高阶组件

    相信不少看过一些框架或者是类库的人都有印象,一个函数叫什么creator或者是什么什么createToFuntion,总是接收一个函数,来返回另一个函数.这是一个高阶函数,它可以接收函数可以当参数,也 ...

  2. React高阶组件学习笔记

    高阶函数的基本概念: 函数可以作为参数被传递,函数可以作为函数值输出. 高阶组件基本概念: 高阶组件就说接受一个组件作为参数,并返回一个新组件的函数. 为什么需要高阶组件 多个组件都需要某个相同的功能 ...

  3. react高阶组件的理解

    [高阶组件和函数式编程] function hello() { console.log('hello jason'); } function WrapperHello(fn) { return fun ...

  4. react高阶组件的一些运用

    今天学习了react高阶组件,刚接触react学习起来还是比较困难,和大家分享一下今天学习的知识吧,另外缺少的地方欢迎补充哈哈 高阶组件(Higher Order Components,简称:HOC) ...

  5. 聊聊React高阶组件(Higher-Order Components)

    使用 react已经有不短的时间了,最近看到关于 react高阶组件的一篇文章,看了之后顿时眼前一亮,对于我这种还在新手村晃荡.一切朝着打怪升级看齐的小喽啰来说,像这种难度不是太高同时门槛也不是那么低 ...

  6. 当初要是看了这篇,React高阶组件早会了

    当初要是看了这篇,React高阶组件早会了. 概况: 什么是高阶组件? 高阶部件是一种用于复用组件逻辑的高级技术,它并不是 React API的一部分,而是从React 演化而来的一种模式. 具体地说 ...

  7. 利用 React 高阶组件实现一个面包屑导航

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

  8. react高阶组件的使用

    为了提高代码的复用在react中我们可以使用高阶组件 1.添加高阶组件 高阶组件主要代码模板HOC.js export default (WrappedComponent) => { retur ...

  9. react高阶组件

    高阶组件 为了提高组件复用性,在react中就有了HOC(Higher-Order Component)的概念.所谓的高阶组件,其本质依旧是组件,只是它返回另外一个组件,产生新的组件可以对属性进行包装 ...

随机推荐

  1. Git——新手入门与上传项目到远程仓库GitHub

    Git:先进的分布式版本控制系统,一个开源式的分布式版本控制工具. Git安装 在Windows操作系统下,访问Git下载地址https://git-for-windows.github.io/ 注册 ...

  2. 读取excel的方法(可用于批量导入)

    FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read); //1. Reading from a binary ...

  3. .net core 导出excel

    1.使用NuGet 安装 EPPlus.Core, 2.代码如下 using OfficeOpenXml; using OfficeOpenXml.Style; public IActionResul ...

  4. 一:Java基础

    /-- 第一章:概念 --/ 1.java特点:跨平台.面向对象.开源 2.JVM是Java虚拟机的缩写,可以实现跨平台 3.java运行原理: 1).编写java源文件,以.java作为后缀名 2) ...

  5. SpringMVC学习笔记:SpringMVC框架的执行流程

    一.MVC设计模式 二.SpringMVC框架介绍 三.SpringMVC环境搭建 四.SpringMVC框架的请求处理流程及体系结构

  6. XML修改节点值

    基于DOM4J 先获取根节点 doc.getRootElement() 然后获取需要修改的节点 doc.getRootElement().node(int) 重新赋值 doc.getRootEleme ...

  7. 撩课-Web大前端每天5道面试题-Day14

    1. 请写出至少5个html5新增的标签,并说明其语义和应用场景? section:定义文档中的一个章节; nav:定义只包含导航链接的章节; header:定义页面或章节的头部; 它经常包含 log ...

  8. hdu 2199 Can you solve this equation? 二分

    Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  9. Github+hexo+next搭建教程

    今天参考的是大神的教程,学了一个新东西,但是可能由于原教程中运用的npm包与我当前使用的npm包版本不同的原因,有出过多处运行错误,但都在此教程中解决了; 总结了下命令: npm install he ...

  10. Java中的继承:父类和子类的关系

    一.父类引用指向子类对象时 1.若子类覆盖了某方法,则父类引用调用子类重新定义的新方法 2.若子类未覆盖某方法,则父类引用调用父类本身的旧方法 3.若子类覆盖了某属性,但父类引用仍调用父类本身的旧属性 ...