国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > iOS > 正文

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

2020-07-26 02:26:01
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

簡(jiǎn)介

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

通過(guò)該文,我們也可以對(duì)native和JS交互方式進(jìn)行初步了解,關(guān)于輸出方法內(nèi)部實(shí)現(xiàn),我們下一篇再剖.

Native module

native module就是實(shí)現(xiàn)了RCTBridgeModule協(xié)議的OC類.RCT就是ReaCT的縮寫.

具體步驟如下

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

輸出組建后,默認(rèn)不會(huì)向JS輸出任何方法,想要輸出方法,需要自定義實(shí)現(xiàn)方法輸出,使用宏RCT_EXPORT_METHOD ()

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

對(duì)于JS端,調(diào)用時(shí)就可以如下

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

注意

向JS輸出的方法名,是RCT_EXPORT_METHOD之后,第一個(gè)冒號(hào)之前的名字.如果native已經(jīng)暴露了多個(gè)冒號(hào)之前同名的方法,RN提供了RCT_REMAP_METHOD ()來(lái)制定方法名.

另外一點(diǎn), RCT_EXPORT_METHOD回調(diào)進(jìn)入的方法,默認(rèn)并不在主線程,如果想要進(jìn)行主線程的方法調(diào)用,需要手動(dòng)進(jìn)行dispatch_async(dispatch_get_main_queue(), ^{});回到主線程

RCT_EXPORT_METHOD參數(shù)

RCT_EXPORT_METHOD支持如下的參數(shù)類型

  • 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支持的類型.

回調(diào)

native module支持回調(diào)類型RCTResponseSenderBlock

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

RCTResponseSenderBlock只支持一個(gè)參數(shù):一個(gè)包含了多個(gè)參數(shù)的數(shù)組.在JS端可以如下,默認(rèn)第一個(gè)參數(shù)是error.當(dāng)沒有錯(cuò)誤時(shí)error為空.

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

native module只能調(diào)用一次回調(diào).如果想傳遞錯(cuò)誤,通過(guò)RCTUtils.h類中的RCTMakeError來(lái)創(chuàng)建.

Promise

Promise是用于實(shí)現(xiàn)異步操作async/await的工具類.如果最后一個(gè)參數(shù)類型為RCTPromiseResolveBlock和RCTPromiseRejectBlock,JS端會(huì)返回一個(gè)promise對(duì)象,進(jìn)行一步操作.

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端因?yàn)楂@取的是promise對(duì)象,可以使用await關(guān)鍵字進(jìn)行異步調(diào)用并等待結(jié)果

async function updateEvents() { try { var events = await CalendarManager.findEvents(); this.setState({events}); } catch (e) { console.error(e); }}updateEvents();

關(guān)于線程

JS執(zhí)行native module是在一個(gè)單獨(dú)的線程實(shí)現(xiàn)的,可以通過(guò)- (dispatch_queue_t)methodQueue來(lái)控制.如果返回主線程,所有執(zhí)行的方法會(huì)在主線程被執(zhí)行.

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

方法methodQueue之后在組件初始化時(shí)被調(diào)用一次.

輸出實(shí)例

除了可以輸出方法,還有輸出實(shí)例.

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

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

只有在初始化時(shí)實(shí)例輸出才是有效的,如果在運(yùn)行時(shí)修改constantsToExport是不會(huì)影響JS環(huán)境的數(shù)據(jù)的.

輸出枚舉

通過(guò)typedef NS_ENUM()定義的枚舉,可以通過(guò)增加RCTConvert的擴(kuò)展來(lái)完成

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

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

native向JS發(fā)方法

想給JS發(fā)方法,可以繼承類RCTEventEmitter,實(shí)現(xiàn)supportedEvents方法,然后通過(guò)調(diào)用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端可以通過(guò)NativeEventEmitter進(jìn)行注冊(cè)和調(diào)用

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 componentWillUnmountsubscription.remove();

注意取消訂閱,一般在componentWillUnmount內(nèi)執(zhí)行.

客戶端可以通過(guò)一些方式獲取JS注冊(cè)和移除訂閱的事件,來(lái)優(yōu)化只在有訂閱者的情況下才發(fā)送事件.

// 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官文

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)武林網(wǎng)的支持。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 安国市| 华容县| 太仆寺旗| 连山| 绥芬河市| 高青县| 招远市| 颍上县| 吕梁市| 都江堰市| 永宁县| 平果县| 精河县| 西贡区| 娱乐| 涞源县| 昌黎县| 高雄县| 聊城市| 哈尔滨市| 旬邑县| 祁东县| 巴彦县| 和政县| 宣城市| 黔西县| 东宁县| 八宿县| 杨浦区| 化州市| 长宁县| 玛沁县| 平利县| 满城县| 莒南县| 新兴县| 垫江县| 九寨沟县| 廉江市| 贺兰县| 盖州市|