React与ES6系列:

  1. React与ES6(一)开篇介绍
  2. React和ES6(二)ES6的类和ES7的property initializer
  3. React与ES6(三)ES6类和方法绑定
  4. React与ES6(四)ES6如何处理React mixins

在使用React.createClass()的时候你也许使用过一个所谓的mixin的东西。使用它,你可以给React组件天剑很多其他的功能。这个概念不止用在React上,也用在很多其他的编程语言或者框架上。

在ES6中不能够在使用React的mixin机制。本文不会纠结于原因为何。我们只关注ES6中的替代方法。

High-Order Component

或者可以叫做高阶组件。

我们使用前文中使用的CartItem组件作为例子,在其中显示一个每秒计数增加1的timer。

为了更好的演示,我们不修改CartItem的代码。相反的我们要提供一些组件,这些组件会封装CartItem并且给CartItem增强一些另外的方法。这样的一个组件就叫做High-Order Comoentn

上面的介绍可能还是有些模糊,不要紧随着本文步步深入一切都会变得清晰。

我们假设这个Hight-Order Component叫做IntervalEnhance,存放在一个叫做intervalEnhance.jsx的文件中。那么我们的CartItem应该怎么改呢?

import React from 'react';
// 1
import {IntervalEnhance} from './IntervalEnhance'; class CartItem extends React.Component {
//...略...
}
//2
export default IntervalEnhance(CartItem);

解释:

  1. 引入高阶组件IntervalEnhance
  2. export高阶组件包装增强后的CartItem

下满就看看告诫组件是怎么定义的:

//@flow

import React from 'react';
//1
export var IntervalEnhance = ComposeComponent => class extends ComposeComponent {
// 2
static displayName = 'ComponentEnhancedWithIntervalHOC'; constructor(props) {
super(props);
this.state = {
seconds: 0
};
}
// 3
componentDidMount() {
this.interval = setInterval(this.tick.bind(this), 1000);
}
// 3
componentWillUnmount() {
clearInterval(this.interval);
} tick() {
this.setState({
seconds: this.state.seconds + 1000
});
} render() {
return (
// 4
<ComposeComponent {...this.props} {...this.state} />
);
}
}

解释:

  1. ComposeComponent => class extends React.Comonent这句。还记得箭头函数吗?没错,这就是一个箭头函数。这个函数接受一个组件为输入参数,返回一个类。ComposedComponent就是输入参数,也就是需要包装增强的组件。export var IntervalEnhance就是把前面定义的函数命名为IntervalEnhance export出去给其他的模块使用。
  2. displayName设定为ComponentEnhancedWithIntervalHOC是为了在DevTools中方便调试。在DevTools里这个组件就会被叫做ComponentEnhancedWithIntervalHOC
  3. 组件生命周期不同阶段的回调。是React组件的内置方法。
  4. 最有意思的就是这里了。这样的写法会把当前高阶组件的全部props和state都发送给CartItem,这样CartItem就可以取到this.state.seconds属性的值了。

最后我们就需要修改CartItem组件的内部了。这样才能输出this.state.seconds的值。

import React from 'react';

import {IntervalEnhance} from './IntervalEnhance';

class CartItem extends React.Component {

    render() {
return (
<article className="row large-4"> <p className="large-12 column" >
<strong>Time elapsed for interval: </strong>
{this.props.seconds} ms
</p> </article>
);
}
}

注意:全部都完成都不需要修改CartItem组件本身(除了render方法)!这就是为什么High-Order Component为什么这里厉害的原因所在。

使用ES7装饰器

使用ES7的装饰器(decorator)代码会更加简洁。

首先,安装babel-plugin-transform-decorators-legacy:

npm install --save-dev babel-plugin-transform-decorators-legacy

之后,配置.babelrc文件:

{
"presets": ["es2015", "react", "stage-0"],
"plugins": [
["transform-decorators-legacy"]
]
}

然后:

import React from 'react';

import {IntervalEnhance} from './intervalEnhance';

@IntervalEnhance
class CartItem extends React.Component {
// ...略...
}

总结

Hight-Order Component(高阶组件)非常好用,也可以非常有效的解决问题。当前,使用高阶组件非常多的用来代替旧的mixin。

有一个典型的例子就是Relay。Relay也是facebook发布的一个完全基于React的framework。你的每一个组件都可以包裹在Relay容器中,自动的存取依赖的数据。

React与ES6(四)ES6如何处理React mixins的更多相关文章

  1. React Native 的ES5 ES6写法对照表

    模块 引用 在ES5里,如果使用CommonJS标准,引入React包基本通过require进行,代码类似这样: //ES5 var React = require("react" ...

  2. React/React Native 的ES5 ES6写法对照表

    //es6与es5的区别很多React/React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component ...

  3. React/React Native 的ES5 ES6写法对照表-b

    很多React/React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component),然而网上搜到的很多教 ...

  4. React Native中常用ES6语法

    一:模块导入导出 //ES6 import React, { Component, PropTypes, } from 'react'; import { Image, Text } from 're ...

  5. 【转】React Native中ES5 ES6写法对照

    很多React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component),然而网上搜到的很多教程和例子都是 ...

  6. React Native之ES5/ES6语法差异对照表

    很多React/React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component),然而网上搜到的很多教 ...

  7. Web 开发的未来:React、Falcor 和 ES6

    Web 开发的未来:React.Falcor 和 ES6 Widen是一家数字资产管理解决方案提供商.目前,其技术栈还非常传统,包括服务器端的Java.浏览器端的AngularJS.提供REST AP ...

  8. 第四章 模块化React和Redux应用

    第四章 模块化React和Redux应用 4.1 模块化应用要点 构建一个应用的基础: 代码文件的组织结构: 确定模块的边界: Store的状态树设计. 4.2 代码文件的组织方式 4.2.1 按角色 ...

  9. SAAS云平台搭建札记: (四) AntD For React使用react-router-dom路由接收不同参数页面不刷新的问题

    在.net开发员眼里,如果使用MVC,根据路由匹配原则,可以通过各种方式接收参数,比如 /Post/List/1, /Post/List/2,或者 /Post/List?id=1,/Post/List ...

随机推荐

  1. java变量的作用域

    1.可分为成员变量和局部变量 两者的作用域不同:局部变量的作用域仅限于定义它的方法,方法外部无法访问,成员变量的作用域在整个类内部都可以访问如果访问权限允许的话,类外部也可以使用 初始值不同:对于成员 ...

  2. SQL SERVER安装序列号

    MICROSOFT SQL SERVER 2012 DEVELOPER 版 序列号:YQWTX-G8T4R-QW4XX-BVH62-GP68Y MICROSOFT SQL SERVER 2012 EN ...

  3. 【Tree 1】树形结构数据呈现的递归算法实现

    一.基本概况 在我的项目中,常常会用到树形结构的数据,最为明显的就是左边菜单栏,类似于window folder一样的东西. 而我之前一直是借助前端封装好的ZTree等工具实现展示,而后台则通常使用递 ...

  4. 使用DotNetOpenAuth搭建OAuth2.0授权框架

    标题还是一如既往的难取. 我认为对于一个普遍问题,必有对应的一个简洁优美的解决方案.当然这也许只是我的一厢情愿,因为根据宇宙法则,所有事物总归趋于混沌,而OAuth协议就是混沌中的产物,不管是1.0. ...

  5. Python自动化 【第五篇】:Python基础-常用模块

    目录 模块介绍 time和datetime模块 random os sys shutil json和pickle shelve xml处理 yaml处理 configparser hashlib re ...

  6. Python urllib模块urlopen()与urlretrieve()详解

    1.urlopen()方法urllib.urlopen(url[, data[, proxies]]) :创建一个表示远程url的类文件对象,然后像本地文件一样操作这个类文件对象来获取远程数据.参数u ...

  7. C++中的左值与右值(二)

    以前以为自己把左值和右值已经弄清楚了,果然发现自己还是太年轻了,下面的这些东西是自己通过在网上拾人牙慧,加上自己的理解写的. 1. 2. 怎么区分左值和右值:知乎大神@顾露的回答. 3. 我们不能直接 ...

  8. apache 泛域名配置

    需求:  在apache上配置两个项目,分别是项目a和项目b,a.baiye5.com访问项目a,其余的除了a前缀名之外的例如b2b.baiye5.com .*.baiye5.com等都访问项目b. ...

  9. HQL

    以下内容全部摘自韩顺平老师Hibernate笔记 * uniqueResult方法 如果我们检索一个对象,明确知道最多只有一个对象,则建议使用该方法: 具体用法如下: Student s=(Stude ...

  10. lucene prefixQuery

    prefixQuery是lucene的一个前缀匹配的搜索功能,但是它的前缀匹配不是完全的前缀匹配,的query生成是:易* 但是能把所有带有易字的都搜到... 下面是实验:出现了交易...