402v /posts/react-nativeru-men-shi-li-jiao-cheng-ge-wan-zheng-de-react-nativeli-zi

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应用时的文档详细,有时需要进入到源码中去找。

Navigator

导航控制器在任何视图构建模式中都是非常重要的组成部分,尤其在大型项目中往往决定了项目的开发复杂度和成本。有关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入门实例教程 - 开始开发

参考连接

评论 · 0

还没有评论。