原生App 与 ReactNative的 数据交互

作者: KumLight | 来源:发表于2017-01-19 10:14 被阅读152次

    RN 开发中 难免会用到原生的一些库和方法 , 因此 RN 与 原生的数据交互 就显得很重要 。 在此整理分享一下。


    原生给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. 调用原生方法
    原生端 实现 RCTBridgeModule协议,并通过RCT_EXPORT_METHOD()宏来实现方法的导出。

    
    @interface RNTestApp ()<RCTBridgeModule>
    
    @end
    
    @implementation RNTestApp
    
    RCT_EXPORT_MODULE();
    
    RCT_EXPORT_METHOD(doSomething:(NSString *)aString withA:(NSString *)a)
    {
      NSLog(@"%@,%@",aString,a);
    }
    

    为了实现RCTBridgeModule协议,你的类需要包含RCT_EXPORT_MODULE()宏。你必须明确的声明要给Javascript导出的方法,否则React Native不会导出任何方法。OC中声明要给Javascript导出的方法,通过RCT_EXPORT_METHOD()宏来实现

    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);
    
    1. 需要引入 NativeModules 模块。
    2. NativeModules.类名.方法名 调用导出的方法。(Manager.doSomething('name','张三'))
    3. 桥接到Javascript的方法返回值类型必须是void。
    4. 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);
    参数只能传一个数组

    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 方法

    有点通知中心的感觉 , 在原生端发送通知 , 然后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函数中实现。
    subscription.remove();
    

    参考文献 :http://www.cnblogs.com/wujy/p/5864591.html

    相关文章

      网友评论

        本文标题:原生App 与 ReactNative的 数据交互

        本文链接:https://www.haomeiwen.com/subject/wkurpttx.html