Native Module у React Native — шта је то, како креирати и интегрисати

Аутор: IT Sectr Објављено: 2026-06-03 Време читања: 9 мин

Native Module је Java или Objective-C класа која чини нативне API-је платформе доступним из JavaScript-а у React Native-у. Сваки модул се региструје у Bridge-у и извози методе које се могу позивати из JS кода као обичне функције. Према подацима Meta, 2024, Native Module остаје основни начин интеграције платформског кода у React Native апликације.

Главно

  • Native Module — мост између JavaScript-а и нативног кода iOS или Android-а.
  • Регистрација — модул се декларише кроз анотације iOS (RCT_EXPORT_MODULE) или Android (@ReactMethod).
  • Типови података — подржани су примитиви, стрингови, низови, речници и Promise.
  • Коришћење — из JS-а модул је доступан преко NativeModules.ИмеМодула.
  • Нова архитектура — у React Native 0.76+ Native Module може радити као Turbo Module преко JSI-ја.

Шта је Native Module?

Native Module је архитектонски елемент React Native-а који омогућава извршавање кода на језику платформе (Objective-C/Swift за iOS, Java/Kotlin за Android) и враћање резултата у JavaScript. Без Native Module-а немогуће је приступити нативним могућностима уређаја — камери, GPS-у, акцелерометру, систему датотека или Bluetooth-у.

React Native долази са сетом уграђених Native Module-а: CameraRoll, AsyncStorage, Geolocation, NetInfo и други. Међутим, за специфичне задатке — интеграцију спољног SDK-ја, рад са хардверским сензорима или позадинске процесе — програмер креира сопствене модуле. Према анкети State of React Native 2024, 67% програмера користи бар један прилагођени Native Module у својим пројектима.

Архитектура Native Module-а зависи од верзије React Native-а. У класичној архитектури (React Native 0.72 и старије) модул се повезује преко Bridge-а и комуницира са JS-ом асинхроно преко JSON серијализације. У новој архитектури (React Native 0.76+) модул може радити као Turbo Module, користећи JSI за синхрони приступ без серијализације.

Креирање Native Module-а за iOS

Креирање Native Module-а за iOS почиње декларацијом Objective-C класе која имплементира протокол RCTBridgeModule. Мацро RCT_EXPORT_MODULE региструје модул у Bridge-у, а RCT_EXPORT_METHOD извози метод доступан из JavaScript-а.

objective-c
// ImageCompressor.m — Native Module за iOS
@interface ImageCompressor () RCT_EXPORT_MODULE()
@end

@implementation ImageCompressor

RCT_EXPORT_METHOD(compressImage:(NSString *)imagePath
                  quality:(NSNumber *)quality
                  resolver:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
    NSData *compressedData = [UIImageJPEGRepresentation(image, quality.floatValue)];
    NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"compressed.jpg"];
    [compressedData writeToFile:outputPath atomically:YES];
    resolve(outputPath);
}

@end

Метод compressImage прима путању до слике и квалитет компресије (0.0–1.0), обрађује податке на нативној страни и враћа путању до компресованог фајла. Кључна предност — компресија се извршава нативним кодом, што је значајно брже и ефикасније по меморији од аналогне операције у JavaScript-у.

За Swift модуле користи се анотација @objc испред класе и метода како би били доступни Objective-C рутајму са којим Bridge ради. Класа мора да наслеђује NSObject и имплементира RCTBridgeModule.

swift
// ImageCompressor.swift — Swift Native Module
@objc(ImageCompressor)
class ImageCompressor: NSObject {

    @objc
    func compressImage(
        _ imagePath: String,
        quality: Float,
        resolver: @escaping RCTPromiseResolveBlock,
        rejecter: @escaping RCTPromiseRejectBlock
    ) {
        guard let image = UIImage(contentsOfFile: imagePath) else {
            rejecter("FILE_ERROR", "Cannot load image", nil)
            return
        }
        guard let data = image.jpegData(compressionQuality: CGFloat(quality)) else {
            rejecter("COMPRESS_ERROR", "Compression failed", nil)
            return
        }
        let outputPath = NSTemporaryDirectory() + "compressed.jpg"
        try? data.write(to: URL(fileURLWithPath: outputPath))
        resolver(outputPath)
    }
}

Креирање Native Module-а за Android

На Android-у Native Module се креира као Java класа која наслеђује ReactContextBaseJavaModule. Анотација @ReactMethod извози метод у Bridge. За враћање резултата користи се интерфејс Promise из com.facebook.react.bridge.

java
// ImageCompressorModule.java — Android Native Module
public class ImageCompressorModule
    extends ReactContextBaseJavaModule {

    @Override
    public String getName() {
        return "ImageCompressor";
    }

    @ReactMethod
    public void compressImage(
            String imagePath,
            Float quality,
            Promise promise) {
        try {
            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
            File outputFile = new File(
                ReactNative.getApplicationContext()
                    .getCacheDir(), "compressed.jpg");
            FileOutputStream fos = new FileOutputStream(outputFile);
            bitmap.compress(
                Bitmap.CompressFormat.JPEG,
                (int)(quality * 100), fos);
            fos.close();
            promise.resolve(outputFile.getAbsolutePath());
        } catch (Exception e) {
            promise.reject("COMPRESS_ERROR", e.getMessage());
        }
    }
}

Метод getName() враћа име модула под којим ће бити доступан из JavaScript-а. У наведеном примеру модул се региструје као ImageCompressor. Анотација @ReactMethod указује Bridge-у да метод треба да буде извезен. Важно: методи морају бити void и прихватати само типове које Bridge подржава: String, Boolean, Integer, Double, ReadableArray, ReadableMap, Promise.

Након креирања класе, модул је потребно регистровати у пакету апликације. За то се креира класа која имплементира ReactPackage и додаје у листу модула у методи createNativeModules.

java
// ImageCompressorPackage.java — регистрација модула
public class ImageCompressorPackage implements ReactPackage {

    @Override
    public List<NativeModule> createNativeModules(
            ReactApplicationContext reactContext) {
        return Arrays.asList(
            new ImageCompressorModule(reactContext)
        );
    }

    @Override
    public List<ViewManager> createViewManagers(
            ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

Регистрација и коришћење Native Module-а

Након креирања модула за обе платформе, потребно их је регистровати у React Native-у. За Android пакет се додаје у MainApplication.java у методу getPackages(). За iOS модул се аутоматски региструје преко макроа RCT_EXPORT_MODULE, али се може користити и ручна регистрација у фајлу AppDelegate.mm.

java
// MainApplication.java — додавање пакета у React Native
import com.yourapp.nativemodules.ImageCompressorPackage;

public class MainApplication extends Application
    implements ReactApplication {

    private final ReactNativeHost mReactNativeHost =
        new ReactNativeHost(this) {

        @Override
        protected List<ReactPackage> getPackages() {
            List<ReactPackage> packages =
                new PackageList(this).getPackages();
            packages.add(new ImageCompressorPackage());
            return packages;
        }
    };
}

Након регистрације, модул постаје доступан у JavaScript-у преко NativeModules-а. React Native аутоматски подмеће име модула наведено у getName() за Android или у RCT_EXPORT_MODULE за iOS.

js
// Коришћење Native Module-а из JavaScript-а
import { NativeModules } from 'react-native';
import { Platform } from 'react-native';

const ImageCompressor = NativeModules.ImageCompressor;

async function compressPhoto(uri: string) {
  try {
    const result = await ImageCompressor.compressImage(
      uri.replace('file://', ''), 0.8
    );
    console.log('Компресовано:', result);
    return result;
  } catch (error) {
    console.error('Компресија неуспешна:', error);
    throw error;
  }
}

Native Module vs Turbo Module: поређење

Поређење класичног Native Module-а и Turbo Module-а помаже да се разуме који приступ одабрати за нови пројекат. Оба механизма пружају приступ нативном коду, али се суштински разликују по архитектури и перформансама.

КарактеристикаNative Module (Bridge)Turbo Module (JSI)
КомуникацијаАсинхрона преко JSON-аСинхрона преко JSI-ја
СеријализацијаJSON при сваком позивуБез копирања података
ТипизацијаРучна, без генерисањаАутоматска преко Codegen-а
УчитавањеПри иницијализацији апликацијеЛења (lazy load)
КомпатибилностСве верзије React Native-аReact Native 0.73+

За постојеће пројекте на React Native 0.72 и старијим, класични Native Module остаје основни избор. За нове пројекте препоручује се коришћење Turbo Module-а, посебно ако је потребна висока перформанса при честим позивима нативних метода. Са постепеним ажурирањем React Native-а, заједница се креће ка потпуном преласку на нову архитектуру.

Често постављана питања

Може ли се проследити callback уместо Promise-а у Native Module-у?

Да, Bridge подржава callback. Уместо Promise-а могу се користити функције повратног позива RCTResponseSenderBlock у iOS-у и Callback у Android-у. Међутим, Promise се сматра савременим стандардом и препоручује се за нове модуле.

Како отклонити грешке у Native Module-у у Xcode-у или Android Studio-у?

Native Module се отклања као обичан нативни код — поставите брејкпоинте у Xcode-у или Android Studio-у. За iOS користите шему изградње са React Native-ом, за Android — Debug конфигурацију. Тачка улаза — методи позвани из JS-а.

Које типове података Native Module НЕ подржава?

Native Module преко Bridge-а не подржава бинарне податке (NSData/byte[]), прилагођене објекте и функције. За пренос слика користите путању до фајла или base64 стринг. Turbo Module преко JSI-ја уклања део ових ограничења.

Да ли је потребно преписивати Native Module при ажурирању React Native-а?

Обично не — Native Module API је стабилан и уназад компатибилан. При преласку на нову архитектуру (Turbo Module) модул се прилагођава преко декоратора, али постојећи код наставља да ради.

Како послати догађај из Native Module-а у JavaScript?

Користите RCTEventEmitter у iOS-у или DeviceEventEmitter у Android-у. Модул шаље догађај, а JS страна се претплаћује преко NativeEventEmitter-а из react-native-а. Ово је корисно за токове података и догађаје сензора.

Завршни преглед

  • Native Module — Java/Objective-C класа која чини нативне API-је доступним из JavaScript-а у React Native-у.
  • Регистрација — iOS користи RCT_EXPORT_MODULE, Android — ReactContextBaseJavaModule са @ReactMethod.
  • Позив — из JS-а модул је доступан преко NativeModules.Модул и подржава Promise и callback.
  • Типови података — Bridge преноси само JSON-компатибилне типове: стрингове, бројеве, низове, речнике.
  • Перформансе — класични Native Module је слабији од Turbo Module-а због асинхроности и серијализације.
  • Миграција — при преласку на React Native 0.76+ модул може радити као Turbo Module без преписивања логике.
  • Примена — Native Module је незаменљив за камеру, Bluetooth, систем датотека и интеграцију SDK-ја.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође