React Native-də Native Module — nədir, necə yaradılır və inteqrasiya edilir

Müəllif: IT Sectr Dərc olunub: 2026-06-03 Oxuma vaxtı: 9 dəq

Native Module — React Native-də JavaScript-dən platformanın nativ API-lərini əlçatan edən Java və ya Objective-C sinifidir. Hər modul Bridge-də qeydiyyatdan keçir və JS kodundan adi funksiyalar kimi çağırıla bilən metodları ixrac edir. Meta, 2024 məlumatlarına görə, Native Module React Native tətbiqlərində platforma kodunun inteqrasiyasının əsas yolu olaraq qalır.

Əsas məqamlar

  • Native Module — JavaScript ilə iOS və ya Android nativ kodu arasında körpü.
  • Qeydiyyat — modul iOS (RCT_EXPORT_MODULE) və ya Android (@ReactMethod) annotasiyaları vasitəsilə elan edilir.
  • Məlumat tipləri — primitivlər, sətirlər, massivlər, lüğətlər və Promise dəstəklənir.
  • İstifadə — JS-dən modula NativeModules.ModulAdı vasitəsilə giriş mümkündür.
  • Yeni arxitektura — React Native 0.76+-da Native Module JSI vasitəsilə Turbo Module kimi işləyə bilər.

Native Module nədir?

Native Module — React Native-in arxitektura elementidir, platforma dilində (iOS üçün Objective-C/Swift, Android üçün Java/Kotlin) kod icra etməyə və nəticəni JavaScript-ə qaytarmağa imkan verir. Native Module olmadan cihazın nativ imkanlarına — kameraya, GPS-ə, akselerometrə, fayl sisteminə və ya Bluetooth-a giriş mümkün deyil.

React Native daxili Native Module dəsti ilə gəlir: CameraRoll, AsyncStorage, Geolocation, NetInfo və s. Lakin spesifik tapşırıqlar üçün — üçüncü tərəf SDK inteqrasiyası, aparat sensorları ilə iş və ya fon prosesləri — tərtibatçı öz modullarını yaradır. State of React Native 2024 sorğusuna görə, tərtibatçıların 67%-i layihələrində ən azı bir xüsusi Native Module istifadə edir.

Native Module arxitekturası React Native versiyasından asılıdır. Klassik arxitekturada (React Native 0.72 və köhnə) modul Bridge vasitəsilə qoşulur və JS ilə JSON serializasiyası vasitəsilə asinxron əlaqə qurur. Yeni arxitekturada (React Native 0.76+) modul Turbo Module kimi işləyə bilər, JSI istifadə edərək serializasiyasız sinxron giriş təmin edir.

iOS üçün Native Module yaradılması

Native Module-in iOS üçün yaradılması RCTBridgeModule protokolunu həyata keçirən Objective-C sinifinin elanı ilə başlayır. RCT_EXPORT_MODULE makrosu modulu Bridge-də qeydiyyatdan keçirir, RCT_EXPORT_METHOD isə JavaScript-dən əlçatan metodu ixrac edir.

objective-c
// ImageCompressor.m — iOS üçün Native Module
@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 metodu şəkilə gedən yolu və sıxılma keyfiyyətini (0.0–1.0) qəbul edir, məlumatları nativ tərəfdə emal edir və sıxılmış fayla gedən yolu qaytarır. Əsas üstünlük — sıxılma nativ kodla yerinə yetirilir, bu da JavaScript-dəki analoji əməliyyatdan qat-qat sürətli və yaddaş baxımından səmərəlidir.

Swift modulları üçün sinif və metodlardan əvvəl @objc anotasiyası istifadə olunur ki, onlar Bridge-in işlədiyi Objective-C mühitində əlçatan olsun. Sinif NSObject-dən miras almalı və RCTBridgeModule-i həyata keçirməlidir.

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)
    }
}

Android üçün Native Module yaradılması

Android-də Native Module ReactContextBaseJavaModule-dən miras alan Java sinifi kimi yaradılır. @ReactMethod anotasiyası metodu Bridge-ə ixrac edir. Nəticəni qaytarmaq üçün com.facebook.react.bridge paketindən Promise interfeysi istifadə olunur.

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() metodu modulun JavaScript-dən əlçatan olacağı adı qaytarır. Verilən nümunədə modul ImageCompressor kimi qeydiyyatdan keçir. @ReactMethod anotasiyası Bridge-ə metodun ixrac edilməli olduğunu göstərir. Əhəmiyyətli: metodlar void olmalı və yalnız Bridge tərəfindən dəstəklənən tipləri qəbul etməlidir: String, Boolean, Integer, Double, ReadableArray, ReadableMap, Promise.

Sinif yaradıldıqdan sonra modul tətbiq paketində qeydiyyatdan keçirilməlidir. Bunun üçün ReactPackage-i həyata keçirən sinif yaradılır və createNativeModules metodunda modullar siyahısına əlavə edilir.

java
// ImageCompressorPackage.java — modul qeydiyyatı
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 qeydiyyatı və istifadəsi

Hər iki platforma üçün modullar yaradıldıqdan sonra onlar React Native-də qeydiyyatdan keçirilməlidir. Android üçün paket MainApplication.java-da getPackages() metoduna əlavə edilir. iOS üçün modul RCT_EXPORT_MODULE makrosu vasitəsilə avtomatik qeydiyyatdan keçir, lakin AppDelegate.mm faylında əl ilə qeydiyyat da mümkündür.

java
// MainApplication.java — paketin React Native-ə əlavə edilməsi
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;
        }
    };
}

Qeydiyyatdan sonra modul JavaScript-də NativeModules vasitəsilə əlçatan olur. React Native avtomatik olaraq Android üçün getName() və ya iOS üçün RCT_EXPORT_MODULE-də göstərilən modul adını əvəz edir.

js
// JavaScript-dən Native Module istifadəsi
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('Sıxıldı:', result);
    return result;
  } catch (error) {
    console.error('Sıxılma uğursuz oldu:', error);
    throw error;
  }
}

Native Module vs Turbo Module: müqayisə

Klassik Native Module və Turbo Module-in müqayisəsi yeni layihə üçün hansı yanaşmanın seçiləcəyini anlamağa kömək edir. Hər iki mexanizm nativ koda giriş təmin edir, lakin arxitektura və performans baxımından prinsipial fərqlənir.

XüsusiyyətNative Module (Bridge)Turbo Module (JSI)
ƏlaqəJSON vasitəsilə asinxronJSI vasitəsilə sinxron
SerializasiyaHər çağırışda JSONMəlumat kopyalanması yoxdur
TipizasiyaƏl ilə, generasiyasızCodegen vasitəsilə avtomatik
YükləməTətbiqin işə salınmasındaGecikmiş (lazy load)
UyğunluqBütün React Native versiyalarıReact Native 0.73+

React Native 0.72 və köhnə versiyalarında olan mövcud layihələr üçün klassik Native Module əsas seçim olaraq qalır. Yeni layihələr üçün Turbo Module-dən istifadə tövsiyə olunur, xüsusən də nativ metodların tez-tez çağırılması zamanı yüksək performans tələb olunarsa. React Native-in tədricən yenilənməsi ilə icma yeni arxitekturaya tam keçidə doğru hərəkət edir.

Tez-tez verilən suallar

Native Module-də Promise əvəzinə callback ötürmək olarmı?

Bəli, Bridge callback-i dəstəkləyir. Promise əvəzinə iOS-da RCTResponseSenderBlock və Android-də Callback geri çağırış funksiyalarından istifadə etmək olar. Lakin Promise müasir standart hesab olunur və yeni modullar üçün tövsiyə edilir.

Xcode və ya Android Studio-da Native Module necə debug edilir?

Native Module adi nativ kod kimi debug edilir — Xcode və ya Android Studio-da breakpoint-lər qoyun. iOS üçün React Native ilə qurma sxemindən, Android üçün Debug konfiqurasiyasından istifadə edin. Giriş nöqtəsi — JS-dən çağırılan metodlardır.

Native Module hansı məlumat tiplərini DƏSTƏKLƏMİR?

Native Module Bridge vasitəsilə ikili məlumatları (NSData/byte[]), xüsusi obyektləri və funksiyaları dəstəkləmir. Şəkilləri ötürmək üçün fayl yolu və ya base64 sətirindən istifadə edin. JSI vasitəsilə Turbo Module bu məhdudiyyətlərin bir hissəsini aradan qaldırır.

React Native yenilənərkən Native Module-i yenidən yazmaq lazımdırmı?

Adətən yox — Native Module API-si sabitdir və geriyə uyğundur. Yeni arxitekturaya (Turbo Module) keçid zamanı modul dekoratorlar vasitəsilə uyğunlaşdırılır, lakin mövcud kod işləməyə davam edir.

Native Module-dən JavaScript-ə hadisə necə göndərilir?

iOS-da RCTEventEmitter, Android-də DeviceEventEmitter istifadə edin. Modul hadisə göndərir, JS tərəfi isə react-native-dən NativeEventEmitter vasitəsilə abunə olur. Bu, axın məlumatları və sensor hadisələri üçün faydalıdır.

Nəticə

  • Native Module — React Native-də JavaScript-dən nativ API-ləri əlçatan edən Java/Objective-C sinifi.
  • Qeydiyyat — iOS RCT_EXPORT_MODULE, Android isə @ReactMethod ilə ReactContextBaseJavaModule istifadə edir.
  • Çağırış — JS-dən modula NativeModules.Modul vasitəsilə giriş mümkündür, Promise və callback dəstəklənir.
  • Məlumat tipləri — Bridge yalnız JSON-uyğun tipləri ötürür: sətirlər, ədədlər, massivlər, lüğətlər.
  • Performans — klassik Native Module asinxronluq və serializasiya səbəbindən Turbo Module-dən geri qalır.
  • Miqrasiya — React Native 0.76+-ya keçid zamanı modul məntiqi yenidən yazılmadan Turbo Module kimi işləyə bilər.
  • Tətbiq — Native Module kamera, Bluetooth, fayl sistemi və SDK inteqrasiyası üçün əvəzolunmazdır.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun