6. Arquitectura de React Native
Tutorial: Arquitectura de React Native - Comprendiendo el Flujo de Comunicación
En este tutorial exploraremos la arquitectura fundamental de React Native basándonos en el diagrama proporcionado, que ilustra la interacción entre el código JavaScript y la plataforma nativa.
🎯 Objetivo del Tutorial
Comprender los tres componentes clave de la arquitectura de React Native y cómo interactúan para renderizar interfaces nativas desde código JavaScript.
📊 Diagrama de Arquitectura (Basado en la Imagen)
text
┌─────────────────────────────────────────────────────────────┐
│ APP (JavaScript) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Components Tree │ │
│ └─────────────────────────────────────────────────────┘ │
│ JS Thread │
└───────────────────────────┬─────────────────────────────────┘
│
┌───────▼────────┐
│ BRIDGE │ ← Comunicación Bidireccional
│ (Puente) │
└───────┬────────┘
│
┌───────────────────────────▼─────────────────────────────────┐
│ PLATFORM OS (Nativo) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Native Thread │ │
│ │ • OEM Widgets (Componentes nativos) │ │
│ │ • Canvas Events (Eventos de pantalla) │ │
│ │ • Location (GPS) │ │
│ │ • Camera (Cámara) │ │
│ │ • Audio (Sonido) │ │
│ │ • Sensors (Sensores) │ │
│ │ • Bluetooth │ │
│ │ • etc. │ │
└─────────────────────────────────────────────────────────────┘
🛠️ Los Tres Componentes Claves
1. JavaScript Thread (Hilo de JavaScript)
Función: Contiene toda la lógica de tu aplicación React Native.
javascript
// Ejemplo típico en App.js
import React from 'react';
import { View, Text, Button } from 'react-native';
function App() {
const [count, setCount] = React.useState(0);
return (
<View>
<Text>Contador: {count}</Text>
<Button
title="Incrementar"
onPress={() => setCount(count + 1)} // Lógica en JavaScript
/>
</View>
);
}
Características:
Ejecuta todo el código JavaScript/TypeScript de tu app
Maneja el estado y la lógica de negocio
Construye el "Virtual DOM" o árbol de componentes
Se ejecuta en un hilo separado del hilo nativo
2. Bridge (Puente)
Función: Canal de comunicación bidireccional entre JavaScript y el mundo nativo.
Cómo funciona:
Serialización: Convierte objetos JavaScript a formato entendible por el nativo
Transferencia: Envía datos a través del límite entre threads
Deserialización: Convierte los datos nuevamente al formato requerido
javascript
// Ejemplo conceptual del Bridge
const bridge = {
// JavaScript → Nativo
sendToNative: (moduleName, methodName, params) => {
// Serializa y envía
},
// Nativo → JavaScript
receiveFromNative: (moduleName, methodName, callback) => {
// Recibe y deserializa
}
};
Tipos de comunicación:
Síncrona: Para operaciones críticas que necesitan respuesta inmediata
Asíncrona: Para la mayoría de operaciones (no bloqueante)
3. Native Thread (Hilo Nativo)
Función: Renderiza la UI y accede a capacidades del dispositivo.
Componentes principales:
🔄 Flujo de Comunicación Paso a Paso
Paso 1: Inicialización
javascript
// JS Thread
const App = () => <View><Text>Hola Mundo</Text></View>;
// Bridge convierte esto a mensaje serializado
// {type: 'CREATE_VIEW', component: 'View', props: {...}}
// Native Thread recibe y crea UIView/ViewGroup correspondiente
Paso 2: Actualización de UI
javascript
// Cuando cambia el estado en JavaScript
setCount(5);
// Bridge envía actualización
// {type: 'UPDATE_PROP', viewId: 123, prop: 'text', value: '5'}
// Native Thread actualiza el TextView nativo
Paso 3: Evento Nativo a JavaScript
java
// En Android (Ejemplo simplificado)
public void onTouchEvent(MotionEvent event) {
// Native Thread detecta toque
WritableMap eventData = Arguments.createMap();
eventData.putInt("x", (int) event.getX());
// Bridge envía a JavaScript
mReactContext.getJSModule(RCTEventEmitter.class)
.receiveEvent(getId(), "topTouch", eventData);
}
Paso 4: JavaScript Maneja el Evento
javascript
// JS Thread recibe el evento
const handleTouch = (event) => {
console.log('Tocado en:', event.nativeEvent.x);
// Actualiza estado, navega, etc.
};
⚡ Ejemplo Práctico: Botón con Acción Nativa
En JavaScript (App.js):
javascript
import { NativeModules, Button } from 'react-native';
const { CameraModule } = NativeModules;
function CameraScreen() {
const takePhoto = async () => {
try {
// Llamada al Bridge → Nativo
const photo = await CameraModule.takePhoto();
console.log('Foto tomada:', photo);
} catch (error) {
console.error('Error:', error);
}
};
return <Button title="Tomar Foto" onPress={takePhoto} />;
}
En Nativo (Android - Java):
java
// CameraModule.java
public class CameraModule extends ReactContextBaseJavaModule {
@ReactMethod
public void takePhoto(Promise promise) {
// Acceso nativo a la cámara
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Bridge maneja la promesa
if (cameraIntent.resolveActivity(getReactApplicationContext().getPackageManager()) != null) {
// Éxito → resuelve promesa en JavaScript
promise.resolve("photo_data_here");
} else {
// Error → rechaza promesa en JavaScript
promise.reject("NO_CAMERA", "No se encontró cámara");
}
}
}
🔍 Optimizaciones y Consideraciones
Limitaciones del Bridge:
Overhead de comunicación: Cada mensaje tiene costo de serialización
No bloqueante: La mayoría de comunicaciones son asíncronas
Serializable solamente: Solo datos serializables pueden cruzar el bridge
Mejores Prácticas:
javascript
// EVITAR: Muchas actualizaciones pequeñas
const BadExample = () => {
const [items, setItems] = useState([]);
// Cada push causa un mensaje al bridge
const addItemsBad = () => {
items.forEach(item => {
setItems(prev => [...prev, item]); // ¡Múltiples actualizaciones!
});
};
// MEJOR: Agrupar actualizaciones
const addItemsGood = () => {
setItems(prev => [...prev, ...newItems]); // Una sola actualización
};
};
🚀 Nuevas Arquitecturas: TurboModules y Fabric
TurboModules:
Reemplazo del sistema de módulos nativos
Lazy loading: Carga módulos solo cuando se necesitan
Type-safe: Definición de tipos compartida
Fabric:
Nuevo sistema de renderizado
Síncrono: Comunicación más directa
Menos serialización: Mejor performance
javascript
// Futuro con Fabric/TurboModules
const FabricComponent = () => {
// Comunicación más eficiente
return <NewFabricView />;
};
✅ Conclusión
Has aprendido que React Native funciona mediante:
JavaScript Thread: Donde vive tu lógica de aplicación
Bridge: El traductor entre JavaScript y nativo
Native Thread: Que renderiza componentes nativos y accede a APIs del dispositivo
Esta arquitectura permite escribir código una vez en JavaScript y ejecutarlo en ambas plataformas, manteniendo la experiencia nativa.
📚 Recursos para Profundizar
¡Felicidades! Ahora comprendes cómo React Native conecta JavaScript con las plataformas nativas, lo que te permitirá desarrollar aplicaciones más eficientes y entender mejor el flujo de datos en tus proyectos.
Comentarios
Publicar un comentario