React-Native入门指南 终章啦,大家猜猜明天会有什么内容更新呢?
六、UI组件
1、目前React-Native支持的组件
在facebook React-native的官网可以看到目前支持的组件如下: https://facebook.github.io/react-native/docs/getting-started.html#content
2、如何正确运行UI组件Example
我们可以到react-native的github项目地址找到example,地址是https://github.com/facebook/react-native/tree/master/Examples/UIExplorer。下载react-native的代码库,将UIExplorer目录下的所有文件拷贝到你新建的项目中。其实UIExplorerApp.js就是整个项目的启动的文件。有两种方式可以启动项目: (1)第一种是修改jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"]; (2)第二种就是将UIExplorerApp.js里面的代码复制到index.ios.js中,此时,注意: AppRegistry.registerComponent('HelloWorld', () => UIExplorerApp); HelloWorld是你的项目名称,如果已经启动项目,需要确保这个名称一致。 项目启动后的界面如下,你就可改改UI组件看效果了。
3、活动指示器组件
其实,每个组件如何使用,可以到demo中去看代码。这里做简单的介绍.活动指示器组件可以做loading,下拉刷新等
4、日历组件
5、图片组件
6、导航器组件
7、导航组件
8、开关组件
其余组件可以查看demo运行和学习,其实就是相当于html标签,具有某种功能,习惯就好。
七、JSX在React-Native中的应用
1、JSX概述
你一定疑问为什么要用JSX?其实这不是必需,而是建议。只是因为React是作为MVC中的V,是为UI而生,所以,React-Native使用JSX更能像HTML样表达树形结构,其实HTML的超类就是XML,React-Native将这个带到了解放前,不可否认的是JSX相比节省了很多的代码。JSX不是什么新奇的东西,JSX只是对JavaScript进行了拓展,仅此而已。
2、语法介绍
(1)类XML UI组件表达,在React-Native中表现为:
render: function() { return ( <View style={styles.container}> <Text style={styles.welcome}> Welcome to React Native! </Text> </View> ); } (2)js表达式 在JSX中,表达式需要{}包裹,例如: render: function() { return ( <View style={styles.container}> <Text style={styles.welcome}> {0? '第一段': '第二段'} </Text> </View> ); }
上面的代码我们可以看出,style={}是一个表达式;{0? '第一段': '第二段'}是表达式,最后显示的应该是“第二段”。
(3)属性 在HTML中,属性可以是任何值,例如:<div tagid="00_1"></div>,tagid就是属性;同样,在组件上可以使用属性。 建议使用以下方式: var props = { tagid: 'GGFSJGFFATQ', poiname: '东方明珠' }; return (<View {...props}></View>); (4)如果需要在调用组件的时候动态增加或者覆盖属性,又该如何呢? 很简单:<View {...props} poiname={'虹桥机场'}></View>
(5)关于样式 1)普通内联样式:{{}},第一层{}是表达式,第二层{}是js对象; <View style={{fontSize:40, width:80,}}> </View> 2)调用样式表:{样式类.属性} <View style={styles.container}></View> 3)样式表和内联样式共存:{[]} <View style={[styles.container, {fontSize:40, width:80}]}> 4)多个样式表:{[样式类1, 样式类2]} <View style={[styles.container, styles.color]}>
(6)属性校验 为了实现强类型语言的效果,我们可以使用propTypes来声明数据属性的合法性校验。例如: React.createClass({ porpTypes:{ username: React.PropTypes.string, age: React.propTypes.number, } }); (7)设定默认属性 React.createClass({ getDefaultProps: function(){ return { sign: '这个家伙很懒,什么都没留下' }; } }); (8)组件的生命周期 componentWillMount:组件创建之前 getInitialState:初始化状态 render:渲染视图 componentDidMount:渲染视图完成后 componentWillUnmount:组件被卸载之前
3、了解虚拟DOM
React进行了虚拟DOM的封装,所有的视图的更新都是虚拟DOM做了一个校验(diff)后最小更新。为什么这么做,因为现在机器的内存已经足以支撑这样视图UI的diff计算,用内存计算换取UI渲染效率。 (1)我们需要获取组件中真实的dom React.findDOMNode(component) (2)第二节已经简单说了组件的生命周期(will, did) 组件的生命周期分为3个部分: Mounting:正在装载组件; Updating:重新计算渲染组件; Unmounting:卸载组件
八、动手写组件
React-Native的核心思想就是组件化,相当于MVC的view,因此开发应用的最佳方式就是将功能组件化。
1、最简单的方式
这里我们实现一个最简单的组件,就是邮件的末尾署名的组件。组件意味着复用,意味着统一。现在有这样一个需求,我们需要根据不同用户发送邮件时,生成每个用户的名片(即邮件末尾的署名)。
(1)一般一开始的实现方式如下,直接将组件内容写到功能需求的地方: <View> <View>..........这里是当前邮件组的其它功能</View> <View> <Text>框架研发部</Text> <Text>www.ctrip.com</Text> </View> </View> (2)有一天,其它的部门的同事提出他们也需要在其他的地方,增加他们的邮件署名,那么你是否又会复制一份代码呢,当然不是,我们可以组件化: var Email = React.createClass({ render: function(){ return ( <View style={styles.container}> <Text style={styles.text}>{this.props.name}</Text> <Text style={styles.text}>{this.props.url}</Text> </View> ); } }); (3)整体的代码如下:
2、循环一个文章列表
要实现的效果如下图:
第一步改造我们的组件 var Article = React.createClass({ render: function(){ return ( <View style={styles.container}> <Text style={[styles.text, styles.title]}>{this.props.title}</Text> <Text style={styles.text}>{this.props.author}</Text> <Text style={styles.text}>{this.props.time}</Text> </View> ); } });
第二步定义数据model和循环
var App = React.createClass({ getInitialState: function(){ var data = [ { title: "React-Native入门指南", author: "vczero", time: "2015-06-28" }, { title: "为什么世界不一样", author: "vczero", time: "2015-06-8" }, { title: "你来,我就告诉你", author: "vczero", time: "2015-04-01" } ]; return { articles: data }; },
render: function(){ return( <ScrollView> {this.state.articles.map(function(article){ return <Article title={article.title} author={article.author} time={article.time}/> })} </ScrollView> ); } }); 整个代码如下:
九、React Native 与 App 集成方案
1、前言
Facebook提供了“Integrating with Existing Apps”方案,但是需要使用pod install
, 会出现版本更新不及时。那么如何手动集成到Native代码中去呢?这里提供一个简单的Demo供参考。
2、构建步骤
(1)创建 React Native项目,目的是获取最新的React Native包 $ react-native init test (2) 创建 Native项目,例如ReactTest (3) 将test/node_modules拷贝到ReactTest根目录下 (4) 在ReactTest项目中创建Group:Libraries (5) 在Group:Libraries中添加依赖的React Native项目: /node_modules/react-native/React/React.xcodeproj /node_modules/react-native/Libraries/Text/RCTText.xcodeproj /node_modules/react-native/Libraries/WebSocket/RCT WebSocket.xcodeproj 添加完成如下图
(6)Build Rules中添加静态库文件,如下图
(7)添加依赖循环
$(SRCROOT)/node_modules/react-native/React 如下图所示:
(8)修改AppDelegate.m应用启动代码
#import "AppDelegate.h"
#import "ViewController.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { if(!self.window){ self.window = [[UIWindow alloc]init]; } self.window.frame = [[UIScreen mainScreen]bounds]; self.window.backgroundColor = [UIColor whiteColor]; self.window.rootViewController = [ViewController new]; [self.window makeKeyAndVisible]; return YES; }
(9)在ViewController.m中调用React Native和Native混编
#import "ViewController.h" #import "RCTRootView.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UIButton *searchBtn = [[UIButton alloc]init]; searchBtn.frame = CGRectMake(0 5, 0, 100, 100); searchBtn.backgroundColor = [UIColor colorWithRed:0.000 green:0.569 blue:1.000 alpha:1]; [searchBtn setTitle:@"搜索" forState:UIControlStateNormal]; [searchBtn setTitle:@"搜索" forState:UIControlStateHighlighted]; NSURL *jsCodeLocation; jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"]; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"Study" initialProperties:nil launchOptions:nil]; rootView.frame = [[UIScreen mainScreen]bounds]; [self.view addSubview:rootView]; [self.view addSubview:searchBtn];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
(10)还需要设置下Other Linker Flags, 如下图
(11)OK 享受编程吧
本文转载自github大咖个人博客,原作者授权发布
原作者:vczero
转自:https://github.com/vczero/react-native-lesson