React Native 入门之Hello Word教程
一、简介
在过去的一年里,React Native还是很火热的,曾有人说将来native的天下要么是React Native,要么是动态插件化开发。不管怎么说都提现了React Native的火热。本文将会介绍react-native的入门级开发---hello world!
首先,React Native是什么?
React Native允许你仅仅使用JavaScript构建app应用,是和react一样的设计。有了React Native,你就无需构建移动web app、html5 app或者混合app等。基于React Native构建的app性能与native相差无几。
完全用javascript就可以构建出一个性能接近native的应用。
二、环境配置
1、安装jdk、idk这里可以自行安装。
jdk:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
sdk:https://stuff.mit.edu/afs/sipb/project/android/docs/sdk/index.html
2、安装node.js
Node.js是一个基于Chrome v8引擎的javascript运行环境,Node.js有全球最大的开源库生态系统npm。node地址:https://nodejs.org/zh-cn/
3、安装React native命令行工具
npm install -g react-native-cli 其中g表示全局安装。
4、创建项目
进入要创建的工程目录,执行 下面命令:
react-native init project 其中project是你要创建的工程名。
5、运行packager
react-native start
执行完上面命令后,可以用浏览器访问:http://localhost:8081/index.android.bundle?platform=android 看看是否成功。
6、运行
这里直接连接真机或者模拟器,执行下面命令即可:
react-native run-android
至此你就可以看到一个hello word的初始化应用了。
三、Hello word项目介绍
1、工程目录结构
上面就是自动生成的工程目录,作为入门级教程,我们关系的最多的就是index.android.js和index.ios.js这是react native应用入口。二者内容一致。
2、index.android.js内容
React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
export default class FirstDemo extends Component {
render() {
return (
Welcome to React Native!
To get started, edit index.ios.js
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
AppRegistry.registerComponent('FirstDemo', () => FirstDemo);
上面代码就是入口文件的内容,以后自己的组件定义也和上面差不多,具体说明如下:(1)每一个组件都会继承react提供的Component类
(2)组件的渲染是有render方法来完成的,当然react有很多生命周期方法,将在下面介绍。
(3)react native提供了很多组件,如View、Text等用于满足开发需求。更多的组件应用查询:http://facebook.github.io/react-native/docs/getting-started.html
(4)react native支持对组件进行样式修饰,具体表现代码就是StyleSheet.create部分。
(5)每个类(组件)一般都会export default,便于引用组件是import。
(6)AppRegistry.registerComponent这个只在入口文件执行一次即可,用于将react native组件与native环境相关联。
四、React生命周期
生命周期对于程序员来说一定是不陌生的,从一个普通对象(一个java对象从产生到消亡)到具体组件(如android中的activity)几乎都有这个概念,react 也不例外,同样为组件提供了生命周期的概念,了解声明周期,明确在那个阶段该做什么事情,具有很重要的意义。下面简述几个常用的:
1、componentWillMount
在完成首次渲染的时候调用,此时可以修改组件是state
2、render
这个就是上面提到的必须要有的方法,创建虚拟dom
3、componentDidMount
真正的dom被渲染后调用,此时可以获取真实dom
4、componentWillReceiveProps
组件接收到新的props时调用,此时可以更改组件props及state;
5、shouldComponentUpdate
组件是否应当渲染新的props和state,返回false表示跳过后续的生命周期方法。
6、componentWillUpdate
接收新的props或者state后,进行渲染之前调用,此时不运行更新props或state。
7、componentDidUpdate
完成渲染新的props或者state后调用
8、componentWillUnmount
类似于destroy,组件消亡之前用于资源回收。与componentDidMount对应。
五、像样点的demo
1、添加tab导航:TabNavigator(详见:https://reactnavigation.org/docs/navigators/tab)
tab导航是当前app最流行的也基本是必备的架构,这样可以充分利用屏幕大小,不同tab页展示不同内容,增加展示丰富度。react相关组件TabNavigator可以提供类似于导航的功能。我们首先搭建这样一个框架。代码如下:
import FirstTabScreen from './screens/FirstTabScreen';
import SecondTabScreen from './screens/SecondTabScreen';
const MainScreenNavigator = TabNavigator({
First: {screen: FirstTabScreen},
Second: {screen: SecondTabScreen},
},{
tabBarPosition: 'bottom',
tabBarOptions: {
indicatorStyle: {
height: 0,
},
activeTintColor: '#ff8500',
inactiveTintColor: '#999',
}
});
export default MainScreenNavigator;
上面代码展示了一个导航架构的实现,由两个只是标签组成。代码说明如下:
TabNavigator接收两个入参:
TabNavigator(RouteConfigs, TabNavigatorConfig)
routeConfigs既是对跳转路由进行配置。上述代码中
First: {screen:FirstTabScreen}既是路由配置,route名称是First,screen对应的则是渲染页面。一个这样的配置对应于一个tab标签,这里配置了两个tab标签。
tabNavigatorConfig是对导航器的一种配置,上述代码中及配置了tabbar的位置为底部、tab激活的背景色以及未激活时的背景色。
这里为每个tab标签配置的标签页分别为FirstTabScreen和SecondTabScreen,对应于具体组件,下面会讲。
2、解决页面跳转:StackNavigator
在小节1中解决了tab框架,但是这里只能做到两个tab之间的切换(即FirstTabScreen和SecondTabScreen之间的切换),但是一个app里面有很多的页面跳转,不可能仅仅只有tab标签页,而StackNavigator就可以解决页面跳转问题。
这里,我们为FirstTabScreen和SecondTabScreen分别配置内部跳转页面FirstTabOne
和FirstTabTwo,而Tab标签页须在主页面展示,配置代码如下:
import React, {Component} from 'react'
import FirstTabOne from '../concrete/FirstTabOne';
import FirstTabTwo from '../concrete/FirstTabTwo'
import {StackNavigator} from 'react-navigation'
import MainScreenNavigator from '../base/MainScreenNavigator'
const ScreenNavigator = StackNavigator({
Home: {screen: MainScreenNavigator},
FirstTabOne: {screen: FirstTabOne},
FirstTabTwo: {screen: FirstTabTwo},
});
export default ScreenNavigator;
上述代码就完成了我们的需求,说明如下:
StackNavigator的函数定义如下:
StackNavigator(RouteConfigs, StackNavigatorConfig)
由此可知,基本与TabNavigator一直,这里就不在啰嗦。
现在配置是配置完了,该有的页面也有了,但是此时还没有逻辑可言,也就是说还没有定义页面之间是如何跳转的。
3、跳转
按照我们2小节中的假设,我们将会为FirstTabScreen和SecondTabScreen分别配置内部跳转页面FirstTabOne和FirstTabTwo,这里我们分别为FirstTabScreen和SecondTabScreen添加跳转按钮,以FirstTabOne为例:
import React, {Component} from 'react'
import {Button, StyleSheet, View} from 'react-native'
export default class FirstTabScreen extends Component {
static navigationOptions = {title: 'first', header: null};
render() {
const {navigate} = this.props.navigation;
return(
);
}
}
const styles = StyleSheet.create({
btnStyle: {
backgroundColor: 'green',
},
viewStyle: {
flex: 1,
justifyContent: 'center',
}
});
如上所示,我们为FirstTabScreen添加了一个button组件,button组件是react native提供的组件,然后为其注册了点击事件,在方法navigate中,我们制定了要跳转到的路由名称FirstTabOne,这个就是在第2小节中routeConfigs中配置的路由名称。这样就可以跳到FirstTabOne页面了。至于返回,StackNavigator已经做了处理,我们无需关心。同样,FirstTabTwo页面也是如此,这里不再粘贴代码。另外需要注意的是,这里跳转页面的时候添加了附加参数:{
title:
'
第一屏
'}
,这个将会在FirstTabOne页面中获取得到,下面会讲到。
4、丰富一下下FirstTabOne页面
在上小节中,我们成功的跳转到了FirstTabOne页面,这里来完善下FirstTabOne页面的展示,采用类似于我们移动开发中经常用到的ListView来丰富下该页面。
(1)FirstTabOne页面实现如下:
import React, {Component} from 'react'
import {ListView, View, Text, StyleSheet, TouchableHighlight} from 'react-native'
import ListViewComponent from './ListViewComponent'
export default class FirstTabOne extends Component {
static navigationOptions = ({navigation}) => ({
title: `${navigation.state.params.title}`
});
render() {
return (
);
}
}
这里在render中我们仅仅调用了ListViewComponent组件,显然这里对ListView做了进一步的封装。
在看ListViewComponent之前,先确认个问题,那就是上节中提到的路由跳转时传入的{title:'第一屏'}参数获取问题,由代码可知,通过
static navigationOptions = ({navigation}) => ({
title: `${navigation.state.params.title}`
});
即可完成该功能。
(2)ListViewComponent实现
import React, {Component} from 'react'
import {ListView, View, Text, StyleSheet, TouchableHighlight} from 'react-native'
import ListViewItem from './ListViewItem'
export default class ListViewComponent extends Component {
constructor(props) {
super(props);
const ds = new ListView.DataSource(
{
rowHasChanged: (r1, r2) => r1 != r2
}
);
this.state = {
dataSource: ds.cloneWithRows(
[
'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
, 'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
, 'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
, 'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
, 'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
, 'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
, 'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
]
),
target: ''
};
}
render() {
return (
{rowData}
}
/>
);
}
}
这里就是ListView的实现,里面展示了静态的文字列表,同时还可以为其中的item添加点击事件,这样就完成了一个像样的demo。
纯手工制作,如有雷同纯属偶然,如有错误,还望指正。
附demo git地址:https://github.com/lvliuji/RN-FirstDemo.git