Native Module a React Native-ban — mi ez, hogyan kell létrehozni és integrálni

Szerző: IT Sectr Megjelenés: 2026-06-03 Olvasási idő: 9 perc

A Native Module egy Java vagy Objective-C osztály, amely a platform natív API-it elérhetővé teszi a JavaScript számára a React Native-ban. Minden modul regisztrálásra kerül a Bridge-ben és olyan metódusokat exportál, amelyek a JS-kódból hétköznapi függvényekként hívhatók meg. A Meta, 2024 adatai szerint a Native Module továbbra is a platformkód integrálásának elsődleges módja a React Native alkalmazásokban.

Főbb pontok

  • Native Module — híd a JavaScript és a natív iOS vagy Android kód között.
  • Regisztráció — a modul iOS (RCT_EXPORT_MODULE) vagy Android (@ReactMethod) annotációkon keresztül kerül deklarálásra.
  • Adattípusok — primitívek, karakterláncok, tömbök, szótárak és Promise támogatottak.
  • Használat — a JS-ből a modul a NativeModules.ModulNév segítségével érhető el.
  • Új architektúra — a React Native 0.76+-ban a Native Module Turbo Module-ként működhet a JSI-n keresztül.

Mi az a Native Module?

Native Module a React Native egy architekturális eleme, amely lehetővé teszi a kód futtatását a platform nyelvén (Objective-C/Swift iOS-hez, Java/Kotlin Android-hoz) és az eredmény visszaküldését a JavaScript-be. Native Module nélkül lehetetlen hozzáférni az eszköz natív képességeihez — kamerához, GPS-hez, gyorsulásmérőhöz, fájlrendszerhez vagy Bluetooth-hoz.

A React Native beépített Native Module-ok készletével érkezik: CameraRoll, AsyncStorage, Geolocation, NetInfo és mások. Azonban specifikus feladatokhoz — harmadik féltől származó SDK integrálása, hardverérzékelőkkel való munka vagy háttérfolyamatok — a fejlesztő saját modulokat hoz létre. A State of React Native 2024 felmérés szerint a fejlesztők 67%-a használ legalább egy egyedi Native Module-t a projektjeiben.

A Native Module architektúrája a React Native verziójától függ. A klasszikus architektúrában (React Native 0.72 és régebbi) a modul a Bridge-en keresztül csatlakozik és aszinkron módon kommunikál a JS-sel JSON szerializáción keresztül. Az új architektúrában (React Native 0.76+) a modul Turbo Module-ként működhet, a JSI-t használva szinkron hozzáféréshez szerializáció nélkül.

Native Module létrehozása iOS-hez

Native Module létrehozása iOS-hez egy Objective-C osztály deklarálásával kezdődik, amely implementálja az RCTBridgeModule protokollt. Az RCT_EXPORT_MODULE makró regisztrálja a modult a Bridge-ben, az RCT_EXPORT_METHOD pedig exportál egy JavaScript-ből elérhető metódust.

objective-c
// ImageCompressor.m — Native Module iOS-hez
@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

A compressImage metódus fogadja a kép elérési útját és a tömörítés minőségét (0.0–1.0), feldolgozza az adatokat a natív oldalon és visszaadja a tömörített fájl elérési útját. A kulcsfontosságú előny — a tömörítés natív kóddal történik, ami jelentősen gyorsabb és memóriahatékonyabb, mint egy hasonló művelet JavaScript-ben.

A Swift modulok esetében az @objc annotációt használjuk az osztály és metódusok előtt, hogy elérhetőek legyenek az Objective-C futási környezet számára, amellyel a Bridge dolgozik. Az osztálynak az NSObject-ből kell örökölnie és implementálnia kell az RCTBridgeModule-t.

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 létrehozása Android-hoz

Androidon a Native Module egy Java osztályként jön létre, amely a ReactContextBaseJavaModule-ből örököl. Az @ReactMethod annotáció exportálja a metódust a Bridge-be. Az eredmény visszaküldéséhez a com.facebook.react.bridge csomag Promise interfészét használjuk.

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

A getName() metódus visszaadja a modul nevét, amely alatt JavaScript-ből elérhető lesz. A megadott példában a modul ImageCompressor néven regisztrálódik. Az @ReactMethod annotáció jelzi a Bridge-nek, hogy a metódust exportálni kell. Fontos: a metódusoknak void-nak kell lenniük és csak a Bridge által támogatott típusokat fogadhatják: String, Boolean, Integer, Double, ReadableArray, ReadableMap, Promise.

Az osztály létrehozása után a modult regisztrálni kell az alkalmazáscsomagban. Ehhez létrejön egy osztály, amely implementálja a ReactPackage-et és hozzáadódik a modulok listájához a createNativeModules metódusban.

java
// ImageCompressorPackage.java — modul regisztráció
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 regisztrációja és használata

A modulok létrehozása után mindkét platformon regisztrálni kell őket a React Native-ban. Android esetén a csomag hozzáadódik a MainApplication.java fájlban a getPackages() metódusban. iOS esetén a modul automatikusan regisztrálódik az RCT_EXPORT_MODULE makrón keresztül, de használható manuális regisztráció is az AppDelegate.mm fájlban.

java
// MainApplication.java — csomag hozzáadása a React Native-hoz
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;
        }
    };
}

Regisztráció után a modul elérhetővé válik JavaScript-ben a NativeModules-on keresztül. A React Native automatikusan behelyettesíti a getName()-ben (Android) vagy az RCT_EXPORT_MODULE-ben (iOS) megadott modulnevet.

js
// Native Module használata JavaScript-ből
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('Tömörítve:', result);
    return result;
  } catch (error) {
    console.error('Tömörítés sikertelen:', error);
    throw error;
  }
}

Native Module vs Turbo Module: összehasonlítás

A klasszikus Native Module és a Turbo Module összehasonlítása segít megérteni, hogy melyik megközelítést válasszuk egy új projekthez. Mindkét mechanizmus hozzáférést biztosít a natív kódhoz, de alapvetően különböznek architektúrában és teljesítményben.

JellemzőNative Module (Bridge)Turbo Module (JSI)
KommunikációAszinkron JSON-on keresztülSzinkron JSI-n keresztül
SzerializációJSON minden híváskorAdatmásolás nélkül
TípizálásKézi, generálás nélkülAutomatikus Codegen-en keresztül
BetöltésAz alkalmazás inicializálásakorLusta (lazy load)
KompatibilitásMinden React Native verzióReact Native 0.73+

A meglévő, React Native 0.72 és régebbi verziójú projektek esetében a klasszikus Native Module marad az elsődleges választás. Új projektekhez a Turbo Module használata ajánlott, különösen ha gyakori natív metódushívásoknál magas teljesítményre van szükség. A React Native fokozatos frissítésével a közösség a teljes átállás felé halad az új architektúrára.

Gyakran ismételt kérdések

Lehet callback-t átadni Promise helyett a Native Module-ban?

Igen, a Bridge támogatja a callback-et. Promise helyett használhatók az RCTResponseSenderBlock visszahívási függvények iOS-ben és a Callback Android-ban. Azonban a Promise modern szabványnak számít és új modulokhoz ajánlott.

Hogyan lehet hibakeresni a Native Module-t Xcode-ban vagy Android Studio-ban?

A Native Module hibakeresése hétköznapi natív kódként történik — állítson be töréspontokat Xcode-ban vagy Android Studio-ban. iOS-hez használja a React Native-val való build sémát, Android-hoz — Debug konfigurációt. A belépési pont — a JS-ből hívott metódusok.

Milyen adattípusokat NEM támogat a Native Module?

Native Module a Bridge-en keresztül nem támogat bináris adatokat (NSData/byte[]), egyedi objektumokat és függvényeket. Képek küldéséhez használjon fájl elérési utat vagy base64 karakterláncot. A Turbo Module a JSI-n keresztül e korlátozások egy részét megszünteti.

Át kell írni a Native Module-t a React Native frissítésekor?

Általában nem — a Native Module API stabil és visszafelé kompatibilis. Az új architektúrára (Turbo Module) való áttéréskor a modul dekorátorokkal adaptálható, de a meglévő kód tovább működik.

Hogyan lehet eseményt küldeni a Native Module-ból JavaScript-be?

Használja az RCTEventEmitter-t iOS-ben vagy a DeviceEventEmitter-t Android-ban. A modul elküldi az eseményt, a JS oldal pedig feliratkozik a react-native NativeEventEmitter-jén keresztül. Ez hasznos adatfolyamokhoz és érzékelő eseményekhez.

Összefoglaló

  • Native Module — Java/Objective-C osztály, amely a natív API-kat elérhetővé teszi a JavaScript-ből a React Native-ban.
  • Regisztráció — iOS az RCT_EXPORT_MODULE-t használja, Android a ReactContextBaseJavaModule-t @ReactMethod-mal.
  • Hívás — JS-ből a modul a NativeModules.Modul segítségével érhető el és támogatja a Promise-t és callback-et.
  • Adattípusok — a Bridge csak JSON-kompatibilis típusokat küld: karakterláncok, számok, tömbök, szótárak.
  • Teljesítmény — a klasszikus Native Module gyengébb a Turbo Module-nál az aszinkronitás és szerializáció miatt.
  • Migráció — a React Native 0.76+-ra való áttéréskor a modul Turbo Module-ként működhet a logika átírása nélkül.
  • Alkalmazás — a Native Module nélkülözhetetlen kamera, Bluetooth, fájlrendszer és SDK integrációhoz.

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is