中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

React Native自定義組件與輸出方法詳解

發布時間:2020-09-24 23:33:43 來源:腳本之家 閱讀:286 作者:sea_biscute 欄目:移動開發

簡介

如果你看的這一篇,需要你對ReactNative的開發有一定的了解,此文講的是在ReactNative提供的組件不能滿足需求,或者native用于較成熟的組件想要輸出,那么就需要用到自定義組件了.

通過該文,我們也可以對native和JS交互方式進行初步了解,關于輸出方法內部實現,我們下一篇再剖.

Native module

native module就是實現了RCTBridgeModule協議的OC類.RCT就是ReaCT的縮寫.

具體步驟如下

  • 引入#import <React/RCTBridgeModule.h>類,然后遵守RCTBridgeModule協議.
  • 實現RCT_EXPORT_MODULE(customName)方法. customName是自定義的組件名,如果不填默認為當前類名.這個組件名是用于向JS輸出.

輸出組建后,默認不會向JS輸出任何方法,想要輸出方法,需要自定義實現方法輸出,使用宏RCT_EXPORT_METHOD ()

RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location)
{
 RCTLogInfo(@"Pretending to create an event %@ at %@", name, location);
}

對于JS端,調用時就可以如下

import {NativeModules} from 'react-native';
var CustomName = NativeModules.CalendarManager;
CustomName.addEvent('Birthday Party', '4 Privet Drive, Surrey');

注意

向JS輸出的方法名,是RCT_EXPORT_METHOD之后,第一個冒號之前的名字.如果native已經暴露了多個冒號之前同名的方法,RN提供了RCT_REMAP_METHOD ()來制定方法名.

另外一點, RCT_EXPORT_METHOD回調進入的方法,默認并不在主線程,如果想要進行主線程的方法調用,需要手動進行dispatch_async(dispatch_get_main_queue(), ^{});回到主線程

RCT_EXPORT_METHOD參數

RCT_EXPORT_METHOD支持如下的參數類型

  • string (NSString)
  • number (NSInteger, float, double, CGFloat, NSNumber)
  • boolean (BOOL, NSNumber)
  • array (NSArray) of any types from this list
  • object (NSDictionary) with string keys and values of any type from this list
  • function (RCTResponseSenderBlock)

也支持所有RCTConvert支持的類型.

回調

native module支持回調類型RCTResponseSenderBlock

RCT_EXPORT_METHOD(findEvents:(RCTResponseSenderBlock)callback)
{
 NSArray *events = ...
 callback(@[[NSNull null], events]);
}

RCTResponseSenderBlock只支持一個參數:一個包含了多個參數的數組.在JS端可以如下,默認第一個參數是error.當沒有錯誤時error為空.

CalendarManager.findEvents((error, events) => {
 if (error) {
 console.error(error);
 } else {
 this.setState({events: events});
 }
});

native module只能調用一次回調.如果想傳遞錯誤,通過RCTUtils.h類中的RCTMakeError來創建.

Promise

Promise是用于實現異步操作async/await的工具類.如果最后一個參數類型為RCTPromiseResolveBlock和RCTPromiseRejectBlock,JS端會返回一個promise對象,進行一步操作.

RCT_REMAP_METHOD(findEvents,
     findEventsWithResolver:(RCTPromiseResolveBlock)resolve
     rejecter:(RCTPromiseRejectBlock)reject)
{
 NSArray *events = ...
 if (events) {
 resolve(events);
 } else {
 NSError *error = ...
 reject(@"no_events", @"There were no events", error);
 }
}

JS端因為獲取的是promise對象,可以使用await關鍵字進行異步調用并等待結果

async function updateEvents() {
 try {
 var events = await CalendarManager.findEvents();

 this.setState({events});
 } catch (e) {
 console.error(e);
 }
}

updateEvents();

關于線程

JS執行native module是在一個單獨的線程實現的,可以通過- (dispatch_queue_t)methodQueue來控制.如果返回主線程,所有執行的方法會在主線程被執行.

- (dispatch_queue_t)methodQueue
{
 return dispatch_get_main_queue();
}

方法methodQueue之后在組件初始化時被調用一次.

輸出實例

除了可以輸出方法,還有輸出實例.

- (NSDictionary *)constantsToExport
{
 return @{ @"firstDayOfTheWeek": @"Monday" };
}

在JS端可以直接獲取console.log(CalendarManager.firstDayOfTheWeek);

只有在初始化時實例輸出才是有效的,如果在運行時修改constantsToExport是不會影響JS環境的數據的.

輸出枚舉

通過typedef NS_ENUM()定義的枚舉,可以通過增加RCTConvert的擴展來完成

@implementation RCTConvert (StatusBarAnimation)
 RCT_ENUM_CONVERTER(UIStatusBarAnimation, (@{ @"statusBarAnimationNone" : @(UIStatusBarAnimationNone),
            @"statusBarAnimationFade" : @(UIStatusBarAnimationFade),
            @"statusBarAnimationSlide" : @(UIStatusBarAnimationSlide)}),
      UIStatusBarAnimationNone, integerValue)
@end

之后就可以通過輸出屬性和方法等方式在JS中使用了.

native向JS發方法

想給JS發方法,可以繼承類RCTEventEmitter,實現supportedEvents方法,然后通過調用self sendEventWithName:即可.

RCT_EXPORT_MODULE();

- (NSArray<NSString *> *)supportedEvents
{
 return @[@"EventReminder"];
}

- (void)calendarEventReminderReceived:(NSNotification *)notification
{
 NSString *eventName = notification.userInfo[@"name"];
 [self sendEventWithName:@"EventReminder" body:@{@"name": eventName}];
}

JS端可以通過NativeEventEmitter進行注冊和調用

import { NativeEventEmitter, NativeModules } from 'react-native';
const { CalendarManager } = NativeModules;

const calendarManagerEmitter = new NativeEventEmitter(CalendarManager);

const subscription = calendarManagerEmitter.addListener(
 'EventReminder',
 (reminder) => console.log(reminder.name)
);
...
// Don't forget to unsubscribe, typically in componentWillUnmount
subscription.remove();

注意取消訂閱,一般在componentWillUnmount內執行.

客戶端可以通過一些方式獲取JS注冊和移除訂閱的事件,來優化只在有訂閱者的情況下才發送事件.

// Will be called when this module's first listener is added.
-(void)startObserving {
 hasListeners = YES;
 // Set up any upstream listeners or background tasks as necessary
}

// Will be called when this module's last listener is removed, or on dealloc.
-(void)stopObserving {
 hasListeners = NO;
 // Remove upstream listeners, stop unnecessary background tasks
}

資料

native modules官文

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

镇安县| 临湘市| 岳西县| 白朗县| 壤塘县| 都昌县| 宣汉县| 清流县| 县级市| 济阳县| 密云县| 若尔盖县| 连云港市| 自贡市| 松江区| 县级市| 枝江市| 大厂| 游戏| 海晏县| 达州市| 鹿泉市| 兰州市| 穆棱市| 潢川县| 南安市| 彰武县| 柳州市| 盈江县| 嘉善县| 陈巴尔虎旗| 昌平区| 赤峰市| 拉孜县| 兴城市| 西乌珠穆沁旗| 阿拉善盟| 共和县| 永春县| 东辽县| 临夏市|