402's Dojo

React Native入门实例教程 - 一个完整的React Native例子

最近一段时间在学习和实践React Native,做一些有趣有用总结和大家分享。这个系列文章可以在这里找到。
在上一篇教程中,我们已经完成了现有项目的React Native开发环境构建。
在开始开发之前,让我们先来看一个React Native代码的实际例子,抛开环境、编译、调试,单纯来整体了解一下React Native的代码。
本文重在流畅的讲解React Native的代码结构,偏重Javascript语法的部分请访问对应的语法讲解文章,后续每篇中文教程都会配备对应的Javascript语法讲解章节。

示例代码全文预览

示例代码如下,你可以把它放到任何一个React Native视图入口文件(如index.ios.js)中:

'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
TouchableOpacity,
} = React;
var SCREEN_WIDTH = require('Dimensions').get('window').width;
var BaseConfig = Navigator.SceneConfigs.FloatFromRight;
var CustomLeftToRightGesture = Object.assign({}, BaseConfig.gestures.pop, {
snapVelocity: 8,
edgeHitWidth: SCREEN_WIDTH,
});
var CustomSceneConfig = Object.assign({}, BaseConfig, {
springTension: 100,
springFriction: 1,
gestures: {
pop: CustomLeftToRightGesture,
}
});
var PageOne = React.createClass({
_handlePress() {
this.props.navigator.push({id: 2,})
},
render() {
return (
<View style={[styles.container, {backgroundColor: 'green'}]}>
<Text style={styles.welcome}>Greetings!</Text>
<TouchableOpacity onPress={this._handlePress}>
// bad case for define style
<View style={{paddingVertical: 10, paddingHorizontal: 20, backgroundColor: 'black'}}>
<Text style={styles.welcome}>Go to page two</Text>
</View>
</TouchableOpacity>
</View>
)
},
);
var PageTwo = React.createClass({
_handlePress() {
this.props.navigator.pop();
},
render() {
return (
<View style={[styles.container, {backgroundColor: 'purple'}]}>
<Text style={styles.welcome}>This is page two!</Text>
<TouchableOpacity onPress={this._handlePress}>
<View style={{paddingVertical: 10, paddingHorizontal: 10, backgroundColor: 'black'}}>
<Text style={styles.welcome}>Go back</Text>
</View>
</TouchableOpacity>
</View>
)
},
});
var SampleApp = React.createClass({
_renderScene(route, navigator) {
if (route.id === 1) {
return <PageOne navigator={navigator} />
} else if (route.id === 2) {
return <PageTwo navigator={navigator} />
}
},
_configureScene(route) {
return CustomSceneConfig;
},
render() {
return (
<Navigator
initialRoute={{id: 1, }}
renderScene={this._renderScene}
configureScene={this._configureScene} />
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
color: 'white',
},
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);
module.exports = SampleApp;

示例代码讲解

use strict

use strict;
Javascritp的严格模式,ECMAScript5后添加的一种条件更为严格的运行模式,能够帮助我们把JS代码写的更加严谨、合理、安全,一些“正常模式“下可以运行的写法到了”严格模式”下可能无法运行。

require - 引入React Native

var react = require('react-native');
require react-native 模块,var react可以理解为创建了一个React类对象。
require方法的作用是加载一个Node.js模块(Module),后续学习过程中也可以用require方法加载图片资源等,这个方法理解起来很重要也需要在JS经验增加的过程中逐步清晰。现在我们只需要知道这里引用了一个React Native定义好的模块就够了。如果想要详细require方法使用的相关知识可以看这里,require方法的设计可以追溯到网页端require.js的使用,其目的都是实现JS文件的异步加载和管理模块之间的相互依赖。

声明本例中使用的React Native组件

var {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
TouchableOpacity,
} = React;

通过var {} = React的格式引入当前js文件环境中会引用到的组件,假如下面的代码中还需要<Image/>这个组件,那么可以把它添加到{}中,这样会创建出这些组件的一个对象,用于后续js代码直接访问。比如:

重要组件说明,后续会有单独的文章分开讲解:

AppRegister

Native和JS沟通的重要桥梁。将当前自定义组件注册成Native可访问的Module,以便Native的React Native视图可以访问这个Module显示到应用中。

StyleSheet

样式表组件,提供类似css-layout的语法,很好的配合了JSX构建视图。详细介绍可以访问这里

View&Text etc.

一些普通的视图组件,比较简单,复杂的也有ScrollView、ListView等。有些是桥接的Native控件
它们是React Native视图的核心组成部分,遗憾的是接口API描述并不明确,没有我们开发iOS或者Android应用时的文档详细,有时需要进入到源码中去找。

导航控制器在任何视图构建模式中都是非常重要的组成部分,尤其在大型项目中往往决定了项目的开发复杂度和成本。有关React Native的Navigator会有专门的文章讲解。传送门

TouchableOpacity

React Native的一个强大之处就在于提供接近于Native的交互体验,比如按钮的按下态,从按钮区域移走之后按下态消失,这在Web App中是可望而不可及的。TouchableOpacity提供了手势相关的,类似于iOS Responder Chain的机制,但在原理上还有不同,想要详细了解请访问这里

定义变量

var SCREEN_WIDTH = require('Dimensions').get('window').width;

Javascript语法定义一个变量,动态载入了一个模块Dimesions,从window属性中拿到屏幕的宽度。

Object.assign() - 补充属性

var CustomLeftToRightGesture = Object.assign({}, BaseConfig.gestures.pop, {
snapVelocity: 8,
edgeHitWidth: SCREEN_WIDTH,
});

Object.assign()方法的作用是从source object拷贝所有可枚举的属性值到target object,然后返回这个target object。

var obj = Object.assign({}, anotherObj, {someproperty: 'I am the value.',});的结构可以简单理解为拷贝一个对象并且添加一些额外的属性。

组件(类)的定义

Javascript for React Native - GUIDE|Styles中我们介绍了Javascript中不适用类。JavaScript 基于 prototype,而不是基于类的。因此React Native和很多JS框架中使用对象来模拟类的概念。

这里创建了一个新的组件(或者说类、对象)。你也可以不调用createClass()方法,这个方法创建的对象中封装了React Native提供的一些基本属性。

组件渲染 - render()方法

你会发现上述方法定义的每个组件类中都会有一个render()方法,这个方法是负责构造当前组件视图的核心方法。render()方法的格式固定为只有一行return语句,返回一个用JSX描述的视图(也可以用原生Javascript语言来描述)。

JSX

JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。React 可以用来做简单的 JSX 句法转换。语法简单易写,比如:

<Text style={styles.welcome}>This is page two!</Text>
<TouchableOpacity onPress={this._handlePress}>
<View style={{paddingVertical: 10, paddingHorizontal: 10, backgroundColor: 'black'}}>
<Text style={styles.welcome}>Go back</Text>
</View>
</TouchableOpacity>
</View>

详细了解可以参考JSX|React

Module - SampleApp

这个例子核心的目的是输出一个名为SampleApp的SampleApp类型的自定义React Native组件。即:

_renderScene(route, navigator) {
if (route.id === 1) {
return <PageOne navigator={navigator} />
} else if (route.id === 2) {
return <PageTwo navigator={navigator} />
}
},
_configureScene(route) {
return CustomSceneConfig;
},
render() {
return (
<Navigator
initialRoute={{id: 1, }}
renderScene={this._renderScene}
configureScene={this._configureScene} />
);
}
});

然后通过AppRegistry注册到Native Modules中以便我们可以在Native代码中这样调用它(以iOS为例,Native视图的创建在后续教程中会详细介绍):

moduleName:moduleName
initialProperties:initialProperties
launchOptions:launchOptions];

Styles

构造视图最主要的就是它的样式,在我们构造组建视图的JSX代码中随处可见这样的代码style={styles.welcome}来为视图指定样式,和HTML的样式指定方式也很相近。
但值得注意的是JSX最终会转换为JS代码,那么welcome这个样式来自于哪儿呢?这样的语法实际上是React Native提供的css-layout,一种用类似css stylesheet方式声明视图样式的方式。

var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
color: 'white',
},
});

React Native中视图样式都是通过上面的方式指定的,结构很简单:通过Stylesheet创建一个对象,create()方法的参数就是一组样式对象作为属性组成的一个大的对象。Styles相关的代码通常放在整个js文件的尾部。
进一步了解Styles in React Native可以访问这里

模块注册

注册成Native Module

将SampleApp注册成Native组件的代码上面已经解释过:

注册成React Module

这个组件除了可以在Native逻辑引用之外,我们也希望让其他js文件引用,因此通过下方的代码注册成JS Module。

一个模块可以通过module.exports或exports将函数、变量等导出,以使其它JavaScript脚本通过require()函数引入并使用。

到这里这篇例子教程就结束了,看这篇例子的目的是对React Native的入口文件index.ios.js有一个整体性的概念,使得在后续开发Native构造视图时不会困惑。

Where to go

React Native入门实例教程 - 开始开发

参考连接

评论