React与ES6系列:

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

前一篇的内容太简单了,会不会很失望。这次就来一个接近实际应用的例子,对应的React的组件也会更加复杂。这次开发一个购物车的页面。在这个页面中你会看到某个产品的信息,比如:图片、名称和价格。另外,一个用户可以增加和减少该商品的数量。

创建cart_item.html

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>React and ES6 Part 2</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/5.5.2/css/foundation.min.css">
</head>
<body>
<div id="root"></div>
<script src="public/cart.bundle.js" type="text/javascript"></script>
</body>
</html>

我们使用了一个CDN来引用样式。添加个样式美化一下这个小应用的内容。dev.root会用来展示React组件生成的内容。

CartItem组件

现在开发Cart组件。创建文件cart.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import CartItem from './cartItem'; const order = {
title: 'Fresh fruits package',
image: 'http://images.all-free-download.com/images/graphiclarge/citrus_fruit_184416.jpg',
initialQty: 3,
price: 8
}; ReactDOM.render(
<CartItem title={order.title}
image={order.image}
initialQty={order.initialQty}
price={order.price} />,
document.getElementById('root')
);

cart.jsx作为购物车功能的总容器。这里引入了reactreact-dom。之后引入了CartItem组件,这个组件会在稍后给出定义。最后,在ReactDom.render方法中把CartItem组件展示在class等于root的HTML元素中。

CartItem组件中的title、image、initialQty和price都是props的值。这些值会在后面CartItem组件的定义中用到。props是组件给子组件传递数据的一种方式。

CartItem组件初步定义

现在应该给出CartItem的定义了。否则整个web app都无法正常运行。CartItem组件可以展示数据,也可以相应用户的增加、减少操作。

import React from 'react';

export default class CartItem extends React.Component {
// 1
constructor(props) {
super(props);
this.state = {
qty: props.initialQty,
total: 0
};
}
// 2
componentWillMount() {
this.recalculateTotal();
}
// 3
increaseQty() {
this.setState({qty: this.state.qty + 1}, this.recalculateTotal);
}
// 3
decreaseQty() {
let newQty = this.state.qty > 0 ? this.state.qty - 1 : 0;
this.setState({qty: newQty}, this.recalculateTotal);
}
// 3
recalculateTotal() {
this.setState({total: this.state.qty * this.props.price});
} render() {
return (
// ...略...
);
}
}

下面解释一下:

  1. constructor是ES6中类的构造函数。整个构造函数需要一个参数props,其全部的值都在上文的代码中给出:title、image等。需要注意的是在构造函数中第一个调用的是super(props)this.state = ...一句中,使用props初始化了整个组件的state初值。
  2. ·componentWillMount()方法是组件的生命周期方法之一。在组件即将在HTML页面中绘制的时候调用。在componentWillMount()中使用方法recalculateTotal()`计算了商品的总价。
  3. 这些是增加、减少商品数量的方法。这些方法在用户点击了增加、减少按钮之后被调用。在这些方法中,更新了state中物品数量的值,并在setState方法的回调中使用了recalculateTotal()方法。

CartItem的render方法

上一节没有给出render方法的具体实现,这里给出:

import React from 'react';

export default class CartItem extends React.Component {
// ...略... render() {
return (
<article className="row large-4">
<figure className="text-center">
<p>
<img src={this.props.image} />
</p>
<figcaption>
<h2>{this.props.title}</h2>
</figcaption>
</figure> <p className="large-4 column"><strong>Quantity: {this.state.qty}</strong></p> <p className="large-4 column">
<button onClick={this.increaseQty.bind(this)} className="button success">+</button>
<button onClick={this.decreaseQty.bind(this)} className="button alert">-</button>
</p> <p className="large-4 column"><strong>Price per item:</strong> ${this.props.price}</p> <h3 className="large-12 column text-center">
Total: ${this.state.total}
</h3> </article>
); }
}

render()方法中,我们使用了JSX语法添加了各种“HTML”节点。这些节点和HTML标签很像,但是并不是HTML元素。

不用担心this.decreaseQty.bind(this)之类的用法。这些会在下一篇里详细解释。

React在ES6中的Default Props和Props类型

假设我们现在需要给CartItem添加一些默认的props,并可以自动检查props的类型。

幸好这些在React里都有内置支持。所以,相关代码非常少。

CartItem类定义的下面直接添加下面的代码:

CartItem.propTypes = {
title: React.PropTypes.string.isRequired,
price: React.PropTypes.number.isRequired,
initialQty: React.PropTypes.number
}; CartItem.defaultProps = {
title: "Indefined Product",
price: 100,
initialQty: 0
};```
这时候如果你在*cart.jsx*文件中给`CartItem`的title值为数值的话,你就会在浏览器中看到警告。 ##在项目中使用ES7
你可能要问了ES6还没整明白的就开始用上ES7了?我要说的是我们往前看,使用一些已经在静态语言里有的特性并不会造成太大的问题。最关键的问题是`Babel`已经支持了。 首先安装必要的`Babel`模块:`npm install --save-dev babel-preset-stage-0`。 然后在*.babelrc*文件中添加这个preset的配置:
```js
{
"presets": ["es2015", "react", "stage-0"]
}

ES7属性初始化器和React组件的Default Props、Props Types

CartItem类里,添加如下代码:

export default class CartItem extends React.Component {
static propTypes = {
title: React.PropTypes.string.isRequired,
price: React.PropTypes.number.isRequired,
initialQty: React.PropTypes.number
};
static defaultProps = {
title: 'Undefined Product',
price: 100,
initialQty: 0
}; constructor(props) {
super(props);
this.state = {
qty: props.initialQty,
total: 0
};
} // ...略...

这样的定义和前面一节在类定义后面再定义default props和props types是一样的效果。但是这样的定义是不是更加的接近静态语言类中定义属性的方式呢?当然之前的default props和props types的定义也可以删去了。

ES7的方式定义React组件的State

最后一步就是把initial state(state初始值)从constructor里拿出来放到property initializer(属性初始化器)里。代码如下:

export default class CartItem extends React.Component {
state = {
qty: this.props.initialQty,
total: 0
}; constructor(props) {
super(props);
// this.state = {
// qty: props.initialQty,
// total: 0
// };
} //...略...
}

记得把原来constructor里的state代码删了。

总结

通过这篇你就可以熟悉了如何用ES6写React的组件,也熟悉了如何使用ES7的property initializer。

React和ES6(二)ES6的类和ES7的property initializer的更多相关文章

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

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

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

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

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

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

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

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

  5. ES6语法:class类,从了解到使用

    前期提要:  JavaScript 语言中,在使用类之前,生成实例对象的传统方法是通过使用构造函数. 一.构造函数: 定义:通过  new 函数名  来实例化对象的函数叫构造函数.   主要功能:为初 ...

  6. ES6中的class类的理解

    传统的javascript中只有对象,没有类的概念.它是基于原型的面向对象语言.原型对象特点就是将自身的属性共享给新对象.这样的写法相对于其它传统面向对象语言来讲,很有一种独树一帜的感脚!非常容易让人 ...

  7. es6 快速入门 系列 —— 类 (class)

    其他章节请看: es6 快速入门 系列 类 类(class)是 javascript 新特性的一个重要组成部分,这一特性提供了一种更简洁的语法和更好的功能,可以让你通过一个安全.一致的方式来自定义对象 ...

  8. react基础用法二(组件渲染)

    react基础用法二(组件渲染) 如图所示组件可以是函数 格式:function 方法名(){ return <标签>内容</标签>} 渲染格式: <方法名 />  ...

  9. [Java聊天室server]实战之二 监听类

    前言 学习不论什么一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列尽管涉及的是socket相关的知识,但学习之前,更 ...

随机推荐

  1. 注册页面JS前台校验

    运行效果图: HTML代码: <script> function checkForm(){ //校验用户名 //获得用户名文本框的值 var username=document.getEl ...

  2. JMeter压力测试以文件的形式

    JMeter压力测试入门教程[图文] 1. 下载JMeter 2. 启动JMeter 3. 运行预准备 4. 运行 文章目录 Apache JMeter是Apache组织开发的基于Java的压力测试工 ...

  3. React 附件动画API ReactCSSTransitionGroup

    React为动画提供了一个附加组件ReactTransitionGroup,这个附加组件是动画的底层API,并且还提供了一个附件组件ReactCSSTransitionGroup,ReactCSSTr ...

  4. 自动化脚本过程中出现This element neither has attached source nor attached Javadoc...的解决方法

    This element neither has attached source nor attached Javadoc and hence no Javadoc could be found Ec ...

  5. myeclipse自动排版

    myeclipse代码排版方式有两种: 1. ctr+f 实现自动排版: 2. myeclipse->Preference->Java->Editor->Sava Action ...

  6. 关于php跨域cookie共享使用方法

    A 服务器所在的域:a1.main.com,A 有应用 main.phpB 服务所在的域:b1.test.com,B 有应用 test.php 1.在 main.php 里设置 cookie 的时候, ...

  7. CentOS6.5 Openssl版本升级

    CentOS6.5  Openssl 升级: 第一步:在openssl官网(https://www.openssl.org/)下载最新版 Ps:个人使用的是openssl-1.0.1u.tar.gz版 ...

  8. 网络存储技术介绍(1) ( based on zt)

    最近由于某同学微信发了一些网络存储的文章,开始感兴趣,稍微收集了一些 一.  网络存储技术 http://ask.zol.com.cn/q/187044.html  (yxr:很老的技术介绍吧) 网络 ...

  9. C# WinForm 单例模式(例:同一个窗体只创建一次实例)

    //C# WinForm 单例模式(例:同一个窗体只创建一次实例) //打开窗体的事件: Form3 f = Form3.InstanceObject() ; //实例化窗体 f.Focus(); / ...

  10. Diagramming for WinForms 教程一(读取图元数据)

    1,新建“Visual c#” Windows窗体应用程序. 2,从“工具箱”的“Diagramming”选项卡下,托出“DiagramView”控件到Form1上.控件的"Name&quo ...