React和ES6(二)ES6的类和ES7的property initializer
React与ES6系列:
- React与ES6(一)开篇介绍
- React和ES6(二)ES6的类和ES7的property initializer
- React与ES6(三)ES6类和方法绑定
- 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作为购物车功能的总容器。这里引入了react和react-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 (
// ...略...
);
}
}
下面解释一下:
constructor是ES6中类的构造函数。整个构造函数需要一个参数props,其全部的值都在上文的代码中给出:title、image等。需要注意的是在构造函数中第一个调用的是super(props)。this.state = ...一句中,使用props初始化了整个组件的state初值。- ·componentWillMount()
方法是组件的生命周期方法之一。在组件即将在HTML页面中绘制的时候调用。在componentWillMount()中使用方法recalculateTotal()`计算了商品的总价。 - 这些是增加、减少商品数量的方法。这些方法在用户点击了增加、减少按钮之后被调用。在这些方法中,更新了
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的更多相关文章
- React Native 的ES5 ES6写法对照表
模块 引用 在ES5里,如果使用CommonJS标准,引入React包基本通过require进行,代码类似这样: //ES5 var React = require("react" ...
- React/React Native 的ES5 ES6写法对照表-b
很多React/React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component),然而网上搜到的很多教 ...
- 【转】React Native中ES5 ES6写法对照
很多React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component),然而网上搜到的很多教程和例子都是 ...
- Web 开发的未来:React、Falcor 和 ES6
Web 开发的未来:React.Falcor 和 ES6 Widen是一家数字资产管理解决方案提供商.目前,其技术栈还非常传统,包括服务器端的Java.浏览器端的AngularJS.提供REST AP ...
- ES6语法:class类,从了解到使用
前期提要: JavaScript 语言中,在使用类之前,生成实例对象的传统方法是通过使用构造函数. 一.构造函数: 定义:通过 new 函数名 来实例化对象的函数叫构造函数. 主要功能:为初 ...
- ES6中的class类的理解
传统的javascript中只有对象,没有类的概念.它是基于原型的面向对象语言.原型对象特点就是将自身的属性共享给新对象.这样的写法相对于其它传统面向对象语言来讲,很有一种独树一帜的感脚!非常容易让人 ...
- es6 快速入门 系列 —— 类 (class)
其他章节请看: es6 快速入门 系列 类 类(class)是 javascript 新特性的一个重要组成部分,这一特性提供了一种更简洁的语法和更好的功能,可以让你通过一个安全.一致的方式来自定义对象 ...
- react基础用法二(组件渲染)
react基础用法二(组件渲染) 如图所示组件可以是函数 格式:function 方法名(){ return <标签>内容</标签>} 渲染格式: <方法名 /> ...
- [Java聊天室server]实战之二 监听类
前言 学习不论什么一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列尽管涉及的是socket相关的知识,但学习之前,更 ...
随机推荐
- 注册页面JS前台校验
运行效果图: HTML代码: <script> function checkForm(){ //校验用户名 //获得用户名文本框的值 var username=document.getEl ...
- JMeter压力测试以文件的形式
JMeter压力测试入门教程[图文] 1. 下载JMeter 2. 启动JMeter 3. 运行预准备 4. 运行 文章目录 Apache JMeter是Apache组织开发的基于Java的压力测试工 ...
- React 附件动画API ReactCSSTransitionGroup
React为动画提供了一个附加组件ReactTransitionGroup,这个附加组件是动画的底层API,并且还提供了一个附件组件ReactCSSTransitionGroup,ReactCSSTr ...
- 自动化脚本过程中出现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 ...
- myeclipse自动排版
myeclipse代码排版方式有两种: 1. ctr+f 实现自动排版: 2. myeclipse->Preference->Java->Editor->Sava Action ...
- 关于php跨域cookie共享使用方法
A 服务器所在的域:a1.main.com,A 有应用 main.phpB 服务所在的域:b1.test.com,B 有应用 test.php 1.在 main.php 里设置 cookie 的时候, ...
- CentOS6.5 Openssl版本升级
CentOS6.5 Openssl 升级: 第一步:在openssl官网(https://www.openssl.org/)下载最新版 Ps:个人使用的是openssl-1.0.1u.tar.gz版 ...
- 网络存储技术介绍(1) ( based on zt)
最近由于某同学微信发了一些网络存储的文章,开始感兴趣,稍微收集了一些 一. 网络存储技术 http://ask.zol.com.cn/q/187044.html (yxr:很老的技术介绍吧) 网络 ...
- C# WinForm 单例模式(例:同一个窗体只创建一次实例)
//C# WinForm 单例模式(例:同一个窗体只创建一次实例) //打开窗体的事件: Form3 f = Form3.InstanceObject() ; //实例化窗体 f.Focus(); / ...
- Diagramming for WinForms 教程一(读取图元数据)
1,新建“Visual c#” Windows窗体应用程序. 2,从“工具箱”的“Diagramming”选项卡下,托出“DiagramView”控件到Form1上.控件的"Name&quo ...