React Native之React速学教程(下)
React Native是基于React的,在开发React Native过程中少不了的需要用到React方面的知识。虽然官方也有相应的Document,但篇幅比较多,学起来比较枯燥。 通过《React Native之React速学教程》你可以对React有更系统和更深入的认识。为了方便大家学习,我将《React Native之React速学教程》分为上、中、下三篇,大家可以根据需要进行阅读学习。 概述本篇为《React Native之React速学教程》的最后一篇。本篇将带着大家一起认识ES6,学习在开发中常用的一些ES6的新特性,以及ES6与ES5的区别,解决大家在学习React /React Native过程中对于ES6与ES5的一些困惑。 ES6的特性何为ES6?ES6全称ECMAScript 6.0,ES6于2015年6月17日发布,ECMAScript是ECMA制定的标准化脚本语言。目前JavaScript使用的ECMAScript版本为ECMAScript-262。 下面我为大家列举了ES6新特性中对我们开发影响比较大的六方面的特性。 1.类(class)对熟悉Java,object-c,c#等纯面向对象语言的开发者来说,都会对class有一种特殊的情怀。ES6 引入了class(类),让JavaScript的面向对象编程变得更加简单和易于理解。 class Animal {
// 构造方法,实例化的时候将会被调用,如果不指定,那么会有一个不带参数的默认构造函数.
constructor(name,color) {
this.name = name;
this.color = color;
}
// toString 是原型对象上的属性
toString() {
console.log('name:' + this.name + ',color:' + this.color);
}
}
var animal = new Animal('dog','white');//实例化Animal
animal.toString();
console.log(animal.hasOwnProperty('name')); //true
console.log(animal.hasOwnProperty('toString')); // false
console.log(animal.__proto__.hasOwnProperty(// true
class Cat extends Animal {
constructor(action) {
// 子类必须要在constructor中指定super 方法,否则在新建实例的时候会报错.
// 如果没有置顶consructor,默认带super方法的constructor将会被添加、
super('cat',68)">'white');
this.action = action;
}
toString() {
console.log(super.toString());
}
}
var cat = new Cat('catch')
cat.toString();
// 实例cat 是 Cat 和 Animal 的实例,和Es5完全一致。
console.log(cat instanceof Cat); // true
console.log(cat instanceof Animal); // true
2.模块(Module)ES5不支持原生的模块化,在ES6中,模块将作为重要的组成部分被添加进来。模块的功能主要由 export 和 import 组成。每一个模块都有自己单独的作用域,模块之间的相互调用关系是通过 export 来规定模块对外暴露的接口,通过import来引用其它模块提供的接口。同时还为模块创造了命名空间,防止函数的命名冲突。 导出(export)ES6允许在一个模块中使用export来导出多个变量或方法。 导出变量 //test.js
export var name = 'Rainbow'
ES6将一个文件视为一个模块,上面的模块通过 export 向外输出了一个变量。一个模块也可以同时往外面输出多个变量。 //test.js
var name = 'Rainbow';
var age = '24';
export {name, age};
导出函数 // myModule.js
export function myModule(someArg) {
return someArg;
}
导入(import)定义好模块的输出以后就可以在另外一个模块通过import引用。 import {myModule} from 'myModule';// main.js
import {name,age} from 'test';// test.js
3.箭头(Arrow)函数 这是ES6中最令人激动的特性之一。 箭头函数的结构箭头函数的箭头=>之前是一个空括号、单个的参数名、或用括号括起的多个参数名,而箭头之后可以是一个表达式(作为函数的返回值),或者是用花括号括起的函数体(需要自行通过return来返回值,否则返回的是undefined)。 // 箭头函数的例子
()=>1
v=>v+1
(a,b)=>a+b
()=>{
alert("foo");
}
e=>{
if (e == 0){
return 0;
}
return 1000/e;
}
卸载监听器时的陷阱
class PauseMenu extends React.Component{
componentWillMount(){
AppStateIOS.addEventListener('change', this.onAppPaused.bind(this));
}
componentDidUnmount(){
AppStateIOS.removeEventListener(this.onAppPaused.bind(this));
}
onAppPaused(event){
}
}
class PauseMenu extends React.Component{
constructor(props){
super(props);
this._onAppPaused = this.onAppPaused.bind(this);
}
componentWillMount(){
AppStateIOS.addEventListener(this._onAppPaused);
}
componentDidUnmount(){
AppStateIOS.removeEventListener(this._onAppPaused);
}
onAppPaused(event){
}
}
除上述的做法外,我们还可以这样做: this.onAppPaused);
}
componentDidUnmount(){
AppStateIOS.removeEventListener(this.onAppPaused);
}
onAppPaused = (event) => {
//把方法直接作为一个arrow function的属性来定义,初始化的时候就绑定好了this指针
}
}
4.ES6不再支持Mixins在ES5下,我们经常使用mixin来为组件添加一些新的方法,如: var SetIntervalMixin = {
componentWillMount: function() {
this.intervals = [];
},
setInterval: function() {
this.intervals.push(setInterval.apply(null, arguments));
},128)">componentWillUnmount: function() {
this.intervals.forEach(clearInterval);
}
};
var TickTock = React.createClass({
mixins: [SetIntervalMixin], // Use the mixin
getInitialState: function() {
return {seconds: 0};
},
...
但,很不幸的是,ES6不支持使用Mixins了,不过我们可以使用,增强组件来替代Mixins。 //Enhance.js
import { Component } from "React";
export var Enhance = ComposedComponent => class extends Component {
constructor() {
this.state = { data: null };
}
componentDidMount() {
this.setState({ data: 'Hello' });
}
render() {
return <ComposedComponent {...this.props} data={this.state.data} />; }
};
//HigherOrderComponent.js
import { Enhance } from "./Enhance";
class MyComponent {
render() {
if (!this.data) return <div>Waiting...</div>; return <div>{this.data}<; }
}
export default Enhance(MyComponent); // Enhanced component
用一个“增强组件”,来为某个类增加一些方法,并且返回一个新类,这无疑能实现mixin所实现的大部分需求。 另外,网上也有很多其他的方案,如react-mixin。 5.ES6不再有自动绑定在ES5中,React.createClass会把所有的方法都bind一遍,这样可以提交到任意的地方作为回调函数,而this不会变化。但在ES6中没有了自动绑定,也就是说,你需要通过bind或者箭头函数来手动绑定this引用。 // 通过使用 bind() 来绑定`this`
<div onClick={this.tick.bind(this)}>
// 也可通过使用箭头函数来实现
<div onClick={() => this.tick()}>
<div onClick={this.tick}> ``` 6.static关键字在ES6中我们可以通过static关键字来定义一个类函数。 class People {
constructor(name) { //构造函数
this.name = name;
}
sayName() {
console.log(this.name);
}
static formatName(name) //将formatName定义为类方法
return name[0].toUpperCase() + name.sustr(1).toLowerCase();
}
}
console.log(People.formatName("tom")); //使用类方法formatName
ES6 VS ES5(ES6与ES5的区别)新版本的React /React Native使用了ES6标准,下面就让我们一起了解一下基于ES6的React/React Native相比ES5有哪些不同。
下面是我们需要知道的ES6与ES5在4大方面上的区别。 1.在定义方面的不同在定义组件,方法,属性等方面,ES6与ES5是有所不同的,下面就让我们一起看一下有哪些不同。
定义组件
在ES5里,通常通过React.createClass来定义一个组件类,像这样: var Photo = React.createClass({
render: function() {
return (
<Image source={this.props.source} /> );
},
});
在ES6里,我们通过继承React.Component 来定义一个组件类,像这样: class Photo extends React.Component {
render() {
return (
<Image source={this.props.source} > );
}
}
定义方法相比ES5,ES6在方法定义上语法更加简洁,从上面的例子里可以看到,给组件定义方法不再用 名字: function()的写法,而是直接用名字(),在方法的最后也不能有逗号了。
test: function(){
},
ES6 class Photo extends React.Component {
test() {
}
render() {
return (
<Image source={this.props.source} > );
}
}
定义组件的属性类型和默认属性在ES5里,属性类型和默认属性分别通过propTypes成员和getDefaultProps方法来实现。 在ES5中,React.createClass会把所有的方法都bind一遍,这样可以提交到任意的地方作为回调函数,而this不会变化。但官方现在逐步认为这反而是不标准、不易理解的。 在ES6下,你需要通过bind来绑定this引用,或者使用箭头函数(它会绑定当前scope的this引用): class PostInfo extends React.Component{ handleOptionsButtonClick(e){ this.setState({showOptionsModal: true}); } render(){ return ( <TouchableHighlight onPress={this.handleOptionsButtonClick.bind(this)} //onPress={e=>this.handleOptionsButtonClick(e)}//这种方式和上面的效果是一样的 > <Text>{this.props.label}<· } |