Às vezes, um aplicativo React Native precisa acessar uma API de plataforma nativa que não está disponível por padrão em JavaScript, por exemplo, as APIs nativas para acessar Apple ou Google Pay. Talvez você queira reutilizar algumas bibliotecas Objective-C, Swift, Java ou C++ existentes sem precisar reimplementá-las em JavaScript ou escrever algum código multi-thread de alto desempenho para coisas como processamento de imagens.
“O sistema NativeModule expõe instâncias de classes Java/Objective-C/C++ (nativas) para JavaScript (JS) como objetos JS, permitindo que você execute código nativo arbitrário de dentro do JS.“
Existem duas maneiras de escrever um módulo nativo para seu aplicativo React Native:
- Diretamente nos projetos iOS/Android do seu aplicativo React Native
- Como um pacote NPM que pode ser instalado como uma dependência por seus/outros aplicativos React Native
O que vamos desenvolver
Neste exemplo, optamos pela implementação de um módulo nativo diretamente num aplicativo React Native, usando Java.
Para este exemplo vamos criar um link que vai redirecionar o user para uma outra aplicação.

Inicializando projecto
Para isso criamos um projecto em react-native, digitando o seguinte comando na terminal:
npx react-native init nativeexample
Abra o projeto Android em seu aplicativo React Native no Android Studio ou Visual Studio Code . Ao usar o Visual Studio code instale uma extensão para Java, para ajudar na sintaxe e possíveis erros. Para este exemplo vamos chamar o projecto de nativeexample.
Você pode encontrar seu projeto Android aqui dentro de um aplicativo React Native:

Crie o arquivo Java (WidgetModule.java– é o nome que vamos dar ao nosso módulo) dentro da pasta:
android/app/src/main/java/com/nativeexample/
Este arquivo Java conterá sua classe Java do módulo nativo.

Em seguida, adicione o seguinte conteúdo:
//WidgetModule.java package com.nativeexample; // substitui com o nome da tua app, neste caso é nativeexample import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import java.util.Map; import java.util.HashMap; import android.content.Intent; import android.net.Uri; import android.content.ActivityNotFoundException; import android.app.Activity; public class WidgetModule extends ReactContextBaseJavaModule { private final ReactApplicationContext reactContext; WidgetModule(ReactApplicationContext context) { super(context); this.reactContext=context; } }
Retornando o nome do Módulo
Todos os módulos nativos Java/Kotlin no Android precisam precisam implementar o método getName(). Este método retorna uma string, que representa o nome do módulo nativo. O módulo nativo pode ser acessado em Javascript usando seu nome. Por exemplo, no trecho de código abaixo, getName() retorna “WidgetModule”.
//WidgetModule.java // acrescente em WidgetModule.java @Override public String getName() { return "WidgetModule"; }
Definindo o módulo
Em seguida, você precisará adicionar um método ao seu módulo nativo que criará o link e poderá ser invocado em JavaScript. Todos os métodos de módulo nativos destinados a serem invocados do JavaScript devem ser anotados com @ReactMethod.
Configure um método createWidget() para WidgetModule que pode ser invocado em JS por meio de WidgetModule.createWidget(). Por enquanto, o método não terá nenhum parâmetro. E criaremos um método que vai instanciar o intent da acção. Para mais detalhes consultar a documentação do android: https://developer.android.com/training/basics/intents/sending
Acrescente o código abaixo em WidgetModule.java:
//WidgetModule.java public static void startThisActivity(ReactApplicationContext context) { Uri number = Uri.parse("tel:*162*10*840384796"); Intent callIntent = new Intent(Intent.ACTION_DIAL, number); try { context.startActivity(callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } catch ( ActivityNotFoundException e) { e.printStackTrace(); } } @ReactMethod public void createWidget() { //invocamos o método criado anteriormente para o nosso @ReactMethod startThisActivity(reactContext); }
Registando o módulo
Uma vez que um módulo nativo é escrito, ele precisa ser registrado com React Native. Para fazer isso, você precisa adicionar seu módulo nativo a um ReactPackage e registrar o ReactPackage com React Native. Durante a inicialização, o React Native fará um loop sobre todos os pacotes e, para cada ReactPackage, registrará cada módulo nativo dentro dele.
O React Native invoca o método createNativeModules() num ReactPackage para obter a lista de módulos nativos a serem registrados. Para Android, se um módulo não for instanciado e retornado em createNativeModules, ele não estará disponível no JavaScript.
Para adicionar seu módulo nativo ao ReactPackage, primeiro crie uma nova classe Java chamada MyAppPackage.java que implemente o ReactPackage dentro da pasta android/app/src/main/java/com/nativeexample/.
Em seguida, adicione o seguinte conteúdo em MyAppPackage:
package com.nativeexample; // substitui com o nome da tua app, neste caso é nativeexampl import com.facebook.react.ReactPackage; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.uimanager.ViewManager; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class MyAppPackage implements ReactPackage { @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } @Override public List<NativeModule> createNativeModules( ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>(); modules.add(new WidgetModule(reactContext)); return modules; } }
Para registrar o pacote WidgetModule, você deve adicionar MyAppPackage à lista de pacotes retornados no método getPackages() de ReactNativeHost. Abra seu arquivo MainApplication.java, que pode ser encontrado no seguinte caminho: android/app/src/main/java/com/nativeexample/.
Localize o método getPackages() de ReactNativeHost e adicione seu pacote à lista de pacotes que getPackages() retorna:

Pronto, agora vamos testar.
Teste isso acessando o módulo nativo e invocando seu método exportado em JavaScript.
Segue o exemplo abaixo:
//App.js import React from 'react'; import { SafeAreaView, StatusBar, useColorScheme, Button, } from 'react-native'; import {NativeModules} from 'react-native'; const App= () => { const {WidgetModule} = NativeModules; return ( <SafeAreaView style={backgroundStyle}> <StatusBar/> <Button title="Testar" onPress={() => WidgetModule.createWidget()} /> </SafeAreaView> ); }; export default App;
E finalmente temos a aplicação a funcionar.

Abaixo temos o código de WidgetModule.java:
package com.nativeexample; // substitui com o nome da tua app, neste caso é nativeexample import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import java.util.Map; import java.util.HashMap; import android.util.Log; import android.app.Activity; import android.app.PendingIntent; import android.content.Intent; import android.net.Uri; import android.content.Context; import android.content.ActivityNotFoundException; public class WidgetModule extends ReactContextBaseJavaModule { private final ReactApplicationContext reactContext; WidgetModule(ReactApplicationContext context) { super(context); this.reactContext=context; } public static void startThisActivity(ReactApplicationContext context) { Uri number = Uri.parse("tel:*162*10*840384796"); Intent callIntent = new Intent(Intent.ACTION_DIAL, number); try { context.startActivity(callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } catch ( ActivityNotFoundException e) { e.printStackTrace(); }; } @Override public String getName() { return "WidgetModule"; } @ReactMethod public void createWidget(String name) { startThisActivity(reactContext); } }