5) React Native 相关JS和React基础

对于没JS以及React开发经验的人(比如我T_T),感觉还是需要简单了解下React Native所应用到的最基础的JS及React知识,才能更近一步地进行React Native开发。

JS_React(图片自p哈哈哈).png

一、JavaScript基础

1. 什么是JavaScript?

JS是一个轻量级的,解释型的讲函数视为一级公民的程序设计语言。他是一种基于原型的多范式动态脚本语言,支持面向对象,命令式编程和函数式编程。

JavaScript的标准是 ECMAScript,React Native的语法是基于ECMAScript 6,简称ES6.(下面文章内容主要是以ES6为标准介绍)

JS的组成:
a) 核心(ECMAScript):描述了该语言的语法和基本对象。担当的是一个翻译的角色;是一个解释器;帮助计算机来读懂我们写的程序;实现加减乘除, 定义变量;
b) 文档对象模型(DOM):描述了处理网页内容的方法和接口。文档指的就是网页;把网页变成一个JS可以操作的对象;给了JS可以操作页面元素的能力;
c) 浏览器对象模型(BOM):描述了与浏览器进行交互的方法和接口。给了JS操作浏览器的能力;

2. JS的基础知识

1) 声明变量,常量
  • var 声明变量,可以在声明的时候初始化为一个值
  • let 声明块范围局部变量,可以在声明的时候初始化一个值
  • const 声明一个只读常量(和let一样只在块级作用域之内有效)

命名规范:命名要以数字字母下划线开头 。
注意点:

  1. JS是大小写敏感的
  2. JS是一个动态类型语言(dynamically typed language)中,所以变量不需声明类型,必要的时候自动转换

举例:

var mainText = "稀饭"
var subText = "欢迎阅读"

调用和显示(在render函数中返回):

return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          {mainText}
        </Text>
        <Text  style={[styles.instructions, {backgroundColor: 'green'}]}>
          {subText}
        </Text>
      </View>
    );

常量可以看到index.ios.js文件最下面有类似,styles就是一个常量:

const styles = StyleSheet.create({....

常量在声明的时候,必须初始化。

在JS中,{} 大括号,表示定义一个对象,大部分情况下要有成对的属性和值,或是函数。
1){mainText}代表一个JS对象,在<Text>显示mainText的内容而不是现实'mainText'字符串。
2)style={[styles.instructions, {backgroundColor: 'green'}]}中,{[...]}为一个数组对象,styles.instructions和{backgroundColor: 'green'}均表示一个JS对象,为数组元素。

2) 流程控制
  • if,else
  • switch
  • for
  • while
  • break
  • continue
    这个各个语言大同小异, 特殊点:JS中的Switch Case中可以是String
3) 注释
// 这是一个单行注释.

/* 这是一个多行注释。
   它可以是任意长度,
   你可以在这里随便写什么。 
*/
4) Promises

** JS本身是单线程的语言,它要实现异步都是通过回调函数来实现的。**
从ES6开始,JS中引入了Promises来处理异步和延迟操作,在React Native的网络请求中是很常见的。
Promises交互主要通过它的then方法,then方法接受一个回调函数,这个回调函数接受执行成功的返回值或执行失败的错误原因,错误原因一般是Error对象。需要注意的是,then方法执行的返回值是一个Promise对象,而then方法接受的回调函数的返回值则可以是任意的JavaScript对象,包括Promises。

例子(简单get网络请求):

fetch(url)
    .then((response) => response.text())
    .then((responseText) => {
      callback1(JSON.parse(responseText));
    })
    .catch((error) => {
      callback2(JSON.parse(error));
    })
    .done();
  }

一个promise有以下几种状态:

  • pending,最初的状态
  • fulfilled,执行成功
  • rejected,执行出错
  • settled,执行结束了,失败(rejected)或者成功(fulfilled)

控制图如下:


控制图.png

目前对promise的理解还停留在网络请求以及在与原生交互的应用上。
这里有一篇推荐的文章,写得像小说一样去理解promise,读读也不错:
ES6 JavaScript Promise的感性认知
也有正常些的文章:初识JavaScript Promises

5) 函数

函数的定义如下,由function关键字声明,在()添加输入,输入不需要声明类型

//在class外,这样的方法是定义在全局的
function globalFunction(input){
    console.log(input);
}

//在class内,当在类中定义的时候,不需要funciton关键字
//通过this.functionName来访问
var mainText = "点击屏幕任意位置"
class JSReactBasics extends Component {
  render() {
    return (
      <TouchableHighlight
        onPress={() => this.backgorundClicked()}
        underlayColor = '#ddd'
        style = {styles.container}
        >
        <Text style={styles.welcome}>{mainText}</Text>
      </TouchableHighlight>
    );
  }
  backgorundClicked(){
    console.log("类中的方法");
  }
}
6) 箭头函数(Arrow functions)

箭头函数=>无疑是ES6中最受关注的一个新特性了,通过它可以简写 function 函数表达式,你也可以在各种提及箭头函数的地方看到这样的观点——“=> 就是一个新的 function”。

onPress={() => this.backgorundClicked()}

这里onPress是一个函数类型(在JS中,函数本身也是一种类型)。这其实是JS中的箭头函数,他提供了一种更简洁的函数表达方式。

var a2 = a.map(function(s){ return s.length });
var a3 = a.map( (s) => s.length );
console.log(a2);
console.log(a3);

可以看到两个log的内容是一样的。(s)用来描述参数,=>后的表示方法的执行体。学过Swift的童鞋,会发现和Swift的必包很像。

注意:
this,在一个类中的不同地方,比如闭包函数中,this的指向并不都是这个类的实例。(经常出问题的地方,需不需要.bind(this))
普通函数.bind(this) 来把内部函数中的 this 绑定到了外部函数去。
箭头函数里的this还是原来的this,不需要额外绑定。

7) 模板字符串

ES6 中引进的一种新型的字符串字面量语法 - 模板字符串。书面上来解释,模板字符串是一种能在字符串文本中内嵌表示式的字符串字面量。简单来讲,就是增加了变量功能的字符串。

模板字符串使用反引号`来代替普通字符串中的用双引号和单引号。模板字符串可以包含特定语法(${expression})的占位符。占位符中的表达式和周围的文本会一起传递给一个默认函数,该函数负责将所有的部分连接起来。

var name = '丁香医生';
var desc = '丁香医生是面向大众的科普性健康类网站';

//Before ES6 字符串拼接
var html = function(name, desc){
    var tpl = '公司名:' + name + '\n'+
            '简介:'+ desc;
    return tpl;
}

//ES6 字符串拼接
var html = `公司名:${name}   
简介:${desc}`;

3. 数据结构和类型

1) 基本数据类型:
  • Boolean,布尔值,true或者false

  • null,一个表明null的特殊关键字,注意JS中大小写敏感,null和NULL是完全不同的东西

  • undefined.变量未定义的属性 (两种情况:1是真的没有定义, 2是虽然定义了,但没有赋值;)

  • Number,数字

  • String,字符串

  • **Symbol **,ES6中新增的,唯一不可变的

  • Object 对象是一个复合类型,它是由一组基本类型组成的;如:div,它是一个对象,它有id,width等特性,它的id是string的,width是number的;

以下值在JS中是会识别为false:

  • false
  • undefined
  • null
  • 0
  • NaN
  • 空字符串 ("")
2) 变量类型转换

检测变量类型: typeof()

  1. parseInt():从字符串中提取数字;
  2. NaN:not a number;
    i. NaN 和任何数计算 都是NaN;
    ii. NaN 不与任何值相等,包括它自身;要比较需要使用方法isNaN();
  3. 显性类型转换:
    i. parseInt()/ parseFloat();
    ii. NaN 的意义和检测:
    意义:not a number;
    检测:isNaN();
  4. 隐式类型转换:
    i. "==" ,就是隐式转换,它会先把两边的东西转成一样的类型,然后再进行比较;
    ii. 减法、乘法、除法 也会进行自发的隐式转换;只有加号不可以;
3) 数组

可以由以下三种方式创建数组,访问数组的方式还是通过角标来访访问:

var a = ["1","2","3","4"];
var b = new Array("1","2","3","4")
var c = Array("1","2","3","4")
console.log(a[1]);

数组有一些方便的方法,例如合并,排序,检索等,可以在MDN上找到

4) 字典Maps(相当于iOS中的NSDictionary)
var map = {"key1":"value1","key2":"value2"}
var map = {"key1":"value1","key2":"value2"}
map["key4"] = "value4"
console.log(map["key1"])
console.log(map["key4"])
5) 对象

JS中的对象的属性可以不先声明,而在运行时候动态添加,例如:

var obj = new Object()
obj.name = "1234"
console.log(obj.name);

所以,在React Native中,写代码的时候,存储数据直接this.propertyName =即可

4. JavaScript是基于原型的面对象语言

理解这一点,对使用JS开发还是比较重要的。
像Java,Objective C,C++都是基于类的面向对象语言。
面向对象语言有两个:

  1. 基于类的面向对象语言主要有两个概念
  • 类(class),定义了一组具有某一类特征的事务。类是抽象的,比如鸟类
  • 实例(instance),实体是类的实体话提现,比如一只鸟
  1. 基于原型的面向对象
  • 基于原型的面向对象语言并不存在这种区别,基于原型的面向对象语言所有的都是对象。基于原型的面向对象语言有一个概念叫做原型对象,古代有一种东西叫做活字印刷术,那一个个字的模版就是这里的原型对象。

React Native引入了基于类的面向对象编程概念,这个在后面讲解React基础的时候来介绍

通过比较Java和JS可以了解二者的区分

|基于类的(Java)|基于原型的(JavaScript)|
| : ------: | : ------: |
|类和实例是不同的事物。|所有对象均为实例。|
|通过类定义来定义类;通过构造器方法来实例化类。|通过构造器函数来定义和创建一组对象。|
|通过 new 操作符创建单个对象。|相同。|
|通过类定义来定义现存类的子类,从而构建对象的层级结构。|指定一个对象作为原型并且与构造函数一起构建对象的层级结构|
|遵循原型链继承属性。|构造器函数或原型指定初始的属性集。允许动态地向单个的对象或者整个对象集中添加或移除属性。|

二、React基础

1. 什么是React?

A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES(一个JavaScript的用来创建界面的库)

通过名字就可以看出来,ReactNative是基于React来写的支持编写原生App的框架。

2. React的基础知识

1) React

React是整个React框架的入口

2) React.Component

Component是React类的基类,类似于iOS的UIView和Android的View,React和React native都定义了很多方便的子类来给开发者使用。

3) React.createClass

创建一个Component

4) Component 相关对象方法

render
调用React.createClass或者让一个类继承自class JSReactBasics extends Component都是需要提供render函数的。这个函数返回一个根的视图,用来渲染实际的Component可视部分,如下:

render() 中 返回的的 JSX 模板需要一个根元素包裹起来

render() {
    return (
      <TouchableHighlight
        onPress={() => this.backgorundClicked()}
        underlayColor = '#ddd'
        style = {styles.container}
        >
        <Text style={styles.welcome}>{mainText}</Text>
      </TouchableHighlight>
    );
  }

getInitialState()
在Component被加载之前调用一次,这个方法的返回值回被设置为this.state

Tips:这个方法只能在用React.createClass创建的时候使用,例如,在我们示例代码中,加入一个方法

getInitialState(){
    return {key:"value"}
  }

getDefaultProps()
在Class 创建的时候,调用一次,这个方法在调用的时候,任何实例还没有被创建。还有一点要注意,这个方法返回的任何Object 对象,在各个实例中是共享的,而不是每个实例一个copy。

5) statics

statics对象,用来定义Components可以调用的静态方法,例如

var MyComponent = React.createClass({
  statics: {
    customMethod: function(foo) {
      return foo === 'bar';
    }
  },
  render: function() {
  }
});

MyComponent.customMethod('bar');  // true

3. 组件的生命周期

个人觉得React Native最核心的概念就是组件了,因此一定需要去理清组件的运作方式,即组件的生命周期,这样才能更合理地去实际应用。
因为组件的生命周期网上有好多好多类似的文章都有详细的描述,这篇文章的内容又已经太多了,所以这里留下一图一表供简单的理解,会在下一篇文章结合ES6对组件的生命周期进行详细描述。

组件的生命周期.png

|生命周期 |调用次数 |能否使用 setSate() |
|: ------:|:------:|:------:|
|defaultProps / getDefaultProps| 1(全局调用一次) | 否
|constructor / getInitialState |1 |否
|componentWillMount |1 |
|render |>=1 |否
|componentDidMount |1 |
|componentWillReceiveProps |>=0 |
|shouldComponentUpdate |>=0 |否
|componentWillUpdate |>=0 |否
|componentDidUpdate |>=0 |否
|componentWillUnmount |1 |否


本文极大的参考了另外一篇文章的篇写,自己也添加了自己的见解和进一步的整理,感谢原文:http://blog.csdn.net/hello_hwc/article/details/51199384

这篇文章整理了下自从入门React Native之后所遇到的关于JS和React基础的知识点,还记得一开始的时候是懵哒到{{}}为啥要这样做都完全不知道,函数也不会调用,总是有this为空,该bind的时候没bind,不该的时候又bind了。。。等等一大堆问题,所以还是觉得先理解好一些最基本的东西才能进行更好的开发。

正在写React Native的学习教程ing,是一边研究一边编写的,已有的成果如下:
1) React Native 简介与入门
2) React Native 环境搭建和创建项目(Mac)
3) React Native 开发之IDE
4) React Native 入门项目与解析

  1. React Native 相关JS和React基础
    6) React Native 组件生命周期(ES6)
    7) React Native 集成到原生项目(iOS)
    8) React Native 与原生之间的通信(iOS)
    9) React Native 封装原生UI组件(iOS)

推荐阅读更多精彩内容