RN 開發(fā)中 難免會用到原生的一些庫和方法 , 因此 RN 與 原生的數(shù)據(jù)交互 就顯得很重要 。 在此整理分享一下。
原生給RN傳參##
主要通過屬性傳值 (props)
原生端 通過向 initialProperties 中添加字典。
NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
NSDictionary *dic = @{@"name" : @"張三"};
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"ReactNativeProject"
initialProperties:dic
launchOptions:launchOptions];
RN端 可以在props 里面直接獲取到
import React, { Component } from 'react';
import {
AppRegistry,
View,
Title,
} from 'react-native';
class RNTestApp extends Component {
render() {
return (
<View>
<Title>{this.props.name}</Title>
</View>
);
}
}
AppRegistry.registerComponent('RNTestApp', () => RNTestApp);
RN調用原生##
1. 調用原生方法
原生端 實現(xiàn) RCTBridgeModule協(xié)議,并通過RCT_EXPORT_METHOD()宏來實現(xiàn)方法的導出。
@interface RNTestApp ()<RCTBridgeModule>
@end
@implementation RNTestApp
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(doSomething:(NSString *)aString withA:(NSString *)a)
{
NSLog(@"%@,%@",aString,a);
}
為了實現(xiàn)RCTBridgeModule協(xié)議,你的類需要包含RCT_EXPORT_MODULE()宏。你必須明確的聲明要給Javascript導出的方法,否則React Native不會導出任何方法。OC中聲明要給Javascript導出的方法,通過RCT_EXPORT_METHOD()宏來實現(xiàn)
RN 端
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Alert,
TouchableHighlight,
} from 'react-native';
import {
NativeModules,
NativeAppEventEmitter
} from 'react-native';
var Manager = NativeModules.RNTestApp;
class ReactNativeProject1 extends Component {
render() {
return (
<TouchableHighlight onPress={()=> Manager.doSomething('name','張三')}>
<Text style={styles.text}>點擊 </Text>
</TouchableHighlight>
);
}
}
const styles = StyleSheet.create({
text: {
flex: 1,
marginTop: 55,
fontWeight: 'bold'
},
});
AppRegistry.registerComponent('ReactNativeProject1', () => ReactNativeProject);
- 需要引入 NativeModules 模塊。
- NativeModules.類名.方法名 調用導出的方法。(Manager.doSomething('name','張三'))
- 橋接到Javascript的方法返回值類型必須是void。
- React Native的橋接是異步操作。
2. 對原生方法 進行回調
原生端 調用 RCTResponseSenderBlock 進行回調
// 對外提供調用方法,演示Callback
RCT_EXPORT_METHOD(testCallbackEvent:(NSDictionary *)dictionary callback:(RCTResponseSenderBlock)callback)
{
NSLog(@"當前名字為:%@",dictionary);
NSArray *events=@[@"張三 ", @"李四 ", @" 王五"];
callback(events);
}
typedef void (^RCTResponseSenderBlock)(NSArray *response);
參數(shù)只能傳一個數(shù)組
import {
NativeModules,
NativeAppEventEmitter
} from 'react-native';
var Manager = NativeModules.RNTestApp;
class ReactNativeProject extends Component {
render() {
return (
<TouchableHighlight onPress={()=>{Manager.testCallbackEvent( {'name':'張三','age':'20'},
(events)=>{
this.setState({events});
}
})
}}>
<Text style={styles.text}>點擊 </Text>
</TouchableHighlight>
);
}
}
原生調用RN 方法
有點通知中心的感覺 , 在原生端發(fā)送通知 , 然后RN端進行攔截。以此來調用RN端方法
- (void)calendarEventReminderReceived:(NSNotification *)notification
{
NSString *name = [notification userInfo][@"name"];
[self.bridge.eventDispatcher sendAppEventWithName:@"EventReminder"
body:@{@"name": name}];
}
import { NativeAppEventEmitter } from 'react-native';
var subscription = NativeAppEventEmitter.addListener(
'EventReminder',
(reminder) => console.log(reminder.name)
);
...
// 千萬不要忘記忘記取消訂閱, 通常在componentWillUnmount函數(shù)中實現(xiàn)。
subscription.remove();