送给做马甲包或者rn初学者的福利。
大概说下这个流程,关于RN项目创建以及热更新配置这里就不详细说明了,人家RN官网讲的挺好的,附上地址:https://github.com/reactnativecn/react-native-pushy/blob/master/docs/guide.md,配置成功之后就是上图这个样子。咱们在这里最主要说的就是“app”这个文件里的东西,关于流程就是index窗口--->NV(Navagitor.js)--->List(选择跳转)--->Detail(web)废话不说上代码.
一、RN部分
1、index.js
import {
AppRegistry
} from 'react-native';
import Navagitor from './app/Navagitor';
AppRegistry.registerComponent('leisureCenterProject', () => Navagitor);
2、Navagitor.js
import React, { Component } from 'react';
import {
NavigatorIOS
} from 'react-native';
import List from './List';
export default class Navagitor extends Component {
render() {
return(
<NavigatorIOS
style={{flex:1}}
initialRoute={{
component: List,
title: '列表',
navigationBarHidden:true,
passProps: {},
}}
/>
);
}
}
3、List.js(选择跳转、热更新都在这里面!)
import React, { Component } from 'react';
import {
StyleSheet,
Platform,
View,
NativeModules,
} from 'react-native';
import {
checkUpdate
} from 'react-native-update';
var RaicngModel = NativeModules.RaicngModel;
import _updateConfig from '../update.json';
import Webdetail from './Webdetail';
const {appKey} = _updateConfig[Platform.OS];
export default class List extends Component {
componentWillMount(){
this.checkUpdate();
}
checkUpdate = () => {
checkUpdate(appKey).then(info => {
if (info.expired) {
this.goTo();
} else if (info.upToDate) {
RaicngModel.calliOSActionGameOther('hello');
} else {
this.goTo();
}
}).catch(err => {
});
};
render() {
return (
<View style={styles.container}>
</View>
);
}
goTo(){
this.props.navigator.replace({
component: Webdetail,
title: '详情',
navigationBarHidden:true,
rightButtonTitle: '收藏',
onRightButtonPress: function(){
alert('点击了收藏按钮。');
}
});
}
}
const styles = StyleSheet.create({
container: { //根View样式
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'white'
}
});
4、Webdetail.js(web页面)
import React, { Component } from 'react';
import {
StyleSheet,
View,
WebView,
Dimensions
} from 'react-native';
const {width, height} = Dimensions.get('window');
export default class Webdetail extends Component {
render() {
return (
<View style={styles.containerweb}>
<WebView
style={{width:width,height:height,backgroundColor:'white'}}
source={{uri:'http://www.jianshu.com/u/29033ec8979e',method: 'GET'}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
containerweb: {
flex: 1,
backgroundColor: '#f2f2f2',
paddingTop:0,
}
});
二、OC部分
RN文件中的List.js里面引用的OC文件RaicngModel是最重要的,它是oc和js的交互文件。
1、RaicngModel.h文件
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
@interface RaicngModel : NSObject<RCTBridgeModule>
@end
2、RaicngModel.m文件
#import "RaicngModel.h"
#import <UIKit/UIKit.h>
#import <React/RCTEventDispatcher.h>
@interface RaicngModel ()
@end
@implementation RaicngModel
@synthesize bridge = _bridge;
//导出模块
RCT_EXPORT_MODULE(); //此处不添加参数即默认为这个OC类的名字
//2个参数
RCT_EXPORT_METHOD(calliOSActionGameOther:(NSString *)name)
{
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter]postNotificationName:@"GameOther" object:nil];
});
}
@end
三、最好把承载rn的视图RCTRootView封装起来,这样子用的时候就很灵活。
.m文件
#import "LuxuryView.h"
#import <React/RCTRootView.h>
#import <React/RCTBundleURLProvider.h>
#import <RCTHotUpdate/RCTHotUpdate.h>
@implementation LuxuryView
-(instancetype)initWithFrame:(CGRect)frame
{
if (self=[super initWithFrame:frame]) {
NSURL *jsCodeLocation;
#ifdef DEBUG
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"pushy" withExtension:@"jsbundle"];
#else
jsCodeLocation=[RCTHotUpdate bundleURL];
#endif
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"leisureCenterProject"initialProperties:nil launchOptions:nil];
[self addSubview:rootView];
rootView.frame =self.bounds;
}
return self;
}
@end