关于 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. WPF 小知识点001

    1.DataGrid 单选事件 <DataGrid MinHeight="150"                  AutoGenerateColumns="Fa ...

  2. flash builder注释字体看不清

    window-preferences-flex-editiors-syntex coloring-ActionScript-Comment (窗口-首选项-flashbuilder-编辑器-语法着色- ...

  3. <深入理解JavaScript>学习笔记(4)_立即调用的函数表达式

    前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行.(小菜理解:的确看到好多,之前都不知道这是自执行匿名函数) 在详细了解这个之前,我们来谈了解一下 ...

  4. WPF实现的简单饼图

    简介 前段时间帮一个同事的忙,利用WPF实现的一个简单饼图,仅能看饼图的比例,无文字查看功能.效果图如下: 用法: var sectorParts = new List<SectorPart&g ...

  5. springboot的依赖注入报null的问题

    最近使用springboot开发项目,使用到了依赖注入,频繁的碰到注入的对象报空指针,错误如下 java.lang.NullPointerException: null at com.mayihc.a ...

  6. sql语句中as的意思是什么?

    as 一般用在两个地方,一个是query的时候,用来重新指定返回的column(列) 名字如:一个table 有个column叫 id, 我们的query是select id from table1. ...

  7. AngularJS+RequireJs实现动态加载JS和页面的方案研究【下】

    about.js: [html] view plain copy 在CODE上查看代码片派生到我的代码片 define(['app'], function(app) { app.controller( ...

  8. Java中的数据类型转换

    先来看一个题: Java类Demo中存在方法func0.func1.func2.func3和func4,请问该方法中,哪些是不合法的定义?( ) public class Demo{ float fu ...

  9. 相比之前其他几个入门的, 推荐: 简单vue2 入门教程

    注意:Vue.js 不支持 IE8 及其以下 IE 版本.       具体可以看下  http://www.runoob.com/vue2/vue-tutorial.html 以下是学习过程 Vue ...

  10. Google APAC----Africa 2010, Qualification Round(Problem C. T9 Spelling)----Perl 解法

    原题地址链接:https://code.google.com/codejam/contest/351101/dashboard#s=p2 问题描述: Problem The Latin alphabe ...