React Native 原生组件开发

React Native 原生组件开发
 最后更新于 2024年10月02日 07:52:54

概要

React Native 的组件开发有三种方式

  • JavaScript 组件
  • Native 组件
  • NativeUI 组件
组件优点缺点
JavaScript组件可复用、低成本、跨平台性能低、复杂需求不能友好支持
Native组件

Native组件

Native 组件开发分为两部分,一部分是 Native 代码,一部分是与之配合的 JavaScript 代码

JavaScript端

const RCTNetInfo = NativeModules.NetInfo;
// 已Promise的形式主动调用Native模块
RCTNetInfo.getCurrentConnectivity().then(resp => resp.network_info);

const NetInfoEventEmitter = new NativeEventEmitter(RCTNetInfo);
// 注册Native模块的事件
NetInfoEventEmitter.addListener('networkStatusDidChange', (appStateData) => {
  handler(appStateData.network_info);
});

Android端

// 定义暴露的方法,以Promise的形式返回结果
@ReactMethod
public void getCurrentConnectivity (Promise promise) {
  promise.resolve(createConnectivityEventMap());
}

// 发送网络状态变更事件
private void sendConnectivityChangedEvent () {
  getReactApplicationContext()
    .getJSModule(RCTDeviceEventEmitter.class)
    .emit('networkStatusDidChange', createConnectivityEventMap());
}

// 创建网络状态变更事件数据
private WritableMap createConnectivityEventMap () {
  WritableMap event = new WritableNativeMap();

  event.putString('network_info', mConnectivity);
  return event;
}

iOS端

// 定义暴露的方法,以Promise的形式返回结果
RCT_EXPORT_METHOD(getCurrentConnectivity:(RCTPromiseResolveBlock)resolve
                  reject:(__unused RCTPromiseRejectBlock)reject)
{
  resolve(@{@"network_info": _status ?: RCTReachabilityStateUnknown});
}

// 发送网络状态变更事件
[self sendEventWithName:@"networkStatusDidChange" body:@{@"network_info": status}];

注意: 数据类型 iOS 下因为有 id 类型,所以限制不大,跟JS对象一致 Android 下需要手动读取对象值

  • Null
  • Boolean
  • Number
  • String
  • Map
  • Array

NativeUI组件

需要定义 ViewManager 和具体 View 的实现,ViewManager 用来创建和管理 View 实例,是 View 实例和 React 之间沟通的桥梁。

AndroidViewManager 可继承自 SimpleViewManagerViewGroupManager

JavaScript端代码

const RCTImageView = requireNativeComponent('RCTImageView', Image);

// 组件代码
<RCTImageView
  {...this.props}
  style={style}
  resizeMode={resizeMode}
  tintColor={tintColor}
  source={sources}/>

Android端

定义组件名称 ViewManager

// 定义组件名称
public static final String REACT_CLASS = 'RCTImageView';

@Override
public String getName () {
  return REACT_CLASS;
}

@ReactProp(name = "src")
public void setSource (ReactImageView view, @Nullable ReadableArray sources) {
  view.setSource(sources);
}

// 创建组件实例
@Override
public ReactImageView createViewInstance (ThemedReactContext context) {
  return new ReactImageView(
    context,
    getDraweeControllerBuilder(),
    getCallerContext()
  );
}