当前位置: 首页 > 科技观察

ReactNative入门项目及分析

时间:2023-03-12 00:52:06 科技观察

通过ReactNative环境构建和创建项目(Mac)可以成功创建新项目,即直接使用如下语句创建://命令行创建项目:react-nativeinitAwesomeProject创建成功,刚刚开始我们主要关注两个文件:1)iOS项目目录下的AppDelegate.m是iOS项目连接js文件及相关初始化操作的入口。2)根目录下的index.ios.js是iOS对应的js入口文件。1、分析iOS工程中的AppDelegate.m1。AppDelegate.m的代码如下:#import"AppDelegate.h"//ReactNative相关头文件#import"RCTBundleURLProvider.h"#import"RCTRootView.h"@implementationAppDelegate-(BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions{NSURL*jsCodeLocation;/*当应用程序开始运行时,RCTRootView会从以下URL加载应用程序:(本地调试时,直接在本地服务器index.ios加载,设置为发布时不同)调用您在运行应用程序时打开的终端窗口,它会打开一个打包程序和服务器来处理上述请求。在Safari中打开该URL;你会看到应用程序的JavaScript代码*/[[RCTBundleURLProvidersharedSettings]setDefaults];jsCodeLocation=[[RCTBundleURLProvidersharedSettings]jsBundleURLForBundleRoot:@"index.ios"fallbackResource:nil];//RCTRootView是一个UIView容器托管ReactNative应用程序。同时,它还提供了连接中国联通原始端和被管理端的接口。RCTRootView*rootView=[[RCTRootViewalloc]initWithBundleURL:jsCodeLocationmoduleName:@"AwesomeProject"initialProperties:nillaunchOptions:launchOptions];rootView.backgroundColor=[[UIColoralloc]initWithRed:1.0fgreen:1.0fblue:1.0falpha:1];[UIWindowalloc]initWithFrame:[UIScreenmainScreen].bounds];UIViewController*rootViewController=[UIViewControllernew];rootViewController.view=rootView;self.window.rootViewController=rootViewController;[self.windowmakeKeyAndVisible];returnYES;}@end2.RCTRootViewRCTRootView将反应Natvie视图被封装到本机组件中。(用户所能看到的一切都来自于这个RootView,所有的初始化工作也是在这个方法中完成的。)分析:可以通过RCTRootView的初始化函数将任何属性传递给ReactNative应用程序。参数initialProperties必须是NSDictionary的实例。这个字典参数会在内部转换成一个JSON对象,可以被JS组件调用。NSArray*imageList=@[@"http://foo.com/bar1.png",@"http://foo.com/bar2.png"];NSDictionary*propsDict=@{@"images":imageList};RCTRootView*rootView=[[RCTRootViewalloc]initWithBundleURL:jsCodeLocationmoduleName:@"AwesomeProject"initialProperties:propsDictlaunchOptions:launchOptions];在js文件中,通过this.props.images调用上面定义的参数。这是通过AppRegistry.registerComponent注册的组件(下文会介绍)RCTRootView还提供了一个可读可写的属性appProperties。设置appProperties后,ReactNative应用程序将根据新属性重新呈现。当然,只有当新属性与之前的属性不同时才会触发更新。(注意:1.属性可以随时更新,但是更新必须在主线程中进行,读取可以在任何线程中进行。2.更新属性时,不能只更新部分属性)NSArray*imageList=@[@"http://foo.com/bar3.png",@"http://foo.com/bar4.png"];rootView.appProperties=@{@"images":imageList};二、解析js入口文件(index.ios.js)1、index.ios.js的代码如下:'usestrict';//全局进入严格模式(目前发现不需要)/**{welcomeText}开始,editindex.android.jsShakeorpressmenubuttonfordevmenutesttouchMe);}//自定义函数touchDown(){//console.log控制台打印,可打印值,多用于调试console.log('>>',this.isTouchDown);if(!this.state.isTouchDown){this.setState({text:'TestTouchDownSuccess',isTouchDown:true});}else{this.setState({text:'TestTouchDownAgainSuccess',isTouchDown:false});}}}//定义样式conststyles=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定义了App的入口,和提供根组件//第一个'AwesomeProject'必须和AppDelegate中注册的moduleName一致//第二个AwesomeProject是入口组件,即上面定义的Component类AppRegistry.registerComponent('AwesomeProject',()=>AwesomeProject);2.运行效果:简单运行效果.png3.基本概念解释1)组件代码中的Text、View、TouchableOpacity都是基本组件。AwesomeProject是自己创建的组件,也是项目的入口组件。在ReactNative项目中,所有显示的界面都可以看作是一个组件(Component),只是功能和逻辑的复杂度不同。每一个都是由很多小组件组成的,每个小组件也有自己对应的逻辑。2)组件的状态和属性组件本质上是状态机,输入确定,输出也必须确定。组件将state和result一一对应,组件中有state和prop(状态和属性)。属性(props)是标签中的属性。组件之前通过标签的属性传递数据,父组件传递给子组件(单向属性传递)。如果组件的某些状态是由外部决定的,并且会影响组件的渲染,那么这些状态应该由props来表示。比如:一个下拉菜单的组件,哪些菜单项是由这个组件的用户和使用场景决定的,那么“菜单项”的状态应该用props来表示,从外部传入。状态(state)是子群中的状态。内部事件方法或者生命周期方法可以调用this.setState来改变。当状态改变时,组件也会触发render函数来更新渲染。如果组件的某些状态需要改变,会影响组件的渲染,那么这些状态应该用state来表示。例如:购物车组件会根据用户在购物车中添加的商品和商品数量显示不同的价格,所以“总价”状态应该用state来表示。