Escribe React Native en el navegador y corre tu primera pantalla en tu propio teléfono, sin instalar nada.
Etiquetas
Por qué empezamos sin instalar nada
Instalar el entorno de React Native es la parte más frustrante del curso y la que menos enseña: Node, el CLI de Expo, el SDK de Android, un emulador que pesa varios gigas. Eso viene la semana que entra.
Hoy la meta es otra y es más importante: que veas tu código corriendo en tu propio teléfono el primer día. Expo Snack lo hace posible — es un editor de React Native que vive en el navegador, con un simulador al lado y un código QR para tu dispositivo real.
Snack tiene límites reales: no sirve para librerías nativas, ni para builds de producción, ni para nada que toque el sistema de archivos. Es un patio de juegos. Para lo de hoy, sobra.
Los tres bloques de un componente
Antes de escribir una línea, aprende a leer el archivo que ya está ahí. Todo componente de React Native tiene la misma anatomía:
javascript1import { StyleSheet, Text, View } from "react-native"; // 1. de dónde vienen las piezas 2 3export default function App() { // 2. el componente 4 return ( 5 <View style={styles.container}> 6 <Text>Open up App.js to start working on your app!</Text> 7 </View> 8 ); 9} 10 11const styles = StyleSheet.create({ // 3. los estilos, como objeto JS 12 container: { flex: 1, alignItems: "center", justifyContent: "center" }, 13});
- Los imports vienen de
react-native, no del DOM. Esa línea es la frontera entre los dos mundos. No existe un<View>global como existe un<div>en HTML: cada componente se trae explícitamente. - El componente es React del que ya conoces. Misma función, mismo
return, mismo JSX. - Los estilos son un objeto de JavaScript. No hay archivo
.css, no hay clases, no hay cascada.StyleSheet.createrecibe un objeto y devuelve estilos que se pasan por la propstyle.
Texto y estilos
En React Native todo texto vive dentro de un <Text>. No es una recomendación: texto suelto dentro de un <View> hace que la app truene.
javascript1<View style={styles.container}> 2 <Text style={styles.titulo}>Hola, soy Nombre</Text> 3 <Text style={styles.sub}>Mi primera app móvil</Text> 4</View>
javascript1titulo: { fontSize: 28, fontWeight: "bold", marginBottom: 8 }, 2sub: { fontSize: 16, color: "#666" },
Fíjate en fontSize: 28. No es "28px". Las unidades con sufijo no existen en React Native: los tamaños son números sin unidad, y equivalen a puntos independientes de densidad (el sistema los escala según la pantalla). Los porcentajes sí van como string (width: "80%"), y esa inconsistencia es una fuente clásica de confusión.
No hay jerarquía tipográfica heredada: no existe un <h1> que ya venga grande. Si quieres que algo parezca un título, lo dices con estilos.
Interacción: onPress, no onClick
javascript1const [conteo, setConteo] = useState(0); 2 3<Pressable style={styles.boton} onPress={() => setConteo(conteo + 1)}> 4 <Text style={styles.textoBoton}>Presióname ({conteo})</Text> 5</Pressable>
Tres cosas que cambian respecto a la web:
onPress, noonClick. No hay mouse. Los eventos son táctiles.- El texto del botón va dentro de un
<Text>.<Pressable>es un contenedor que responde al tacto, no un botón con etiqueta. useStatees exactamente el mismo hook que ya conoces. Lo que cambia es el componente que lo rodea, nunca la lógica ni el estado.
Existe también <Button>, más simple pero casi imposible de estilar y con apariencia distinta en iOS y Android. En cuanto quieras control visual vas a usar Pressable.
Verlo en tu teléfono
- Instala Expo Go desde la App Store o Google Play.
- En Snack, abre la pestaña My Device: aparece un código QR.
- Escanéalo — con la cámara en iOS, con la propia app de Expo Go en Android.
- Tu teléfono y tu computadora deben estar en la misma red.
A partir de ahí, cada cambio que guardes en Snack se refleja solo en el teléfono. Si el QR no conecta, casi siempre es que el teléfono está en datos móviles y no en el WiFi.
Errores típicos del primer día
| Qué haces | Qué pasa |
|---|---|
Texto suelto fuera de un <Text> | La app truena con un error explícito |
fontSize: "20px" | Falla o se ignora: los números van sin unidad |
Olvidar el import de un componente | Error en tiempo de ejecución, no al escribir |
<Image> sin width ni height | Falla en silencio: mide 0×0 y simplemente no se ve |
El último es el importante. Los tres primeros gritan; el cuarto no dice nada y te deja mirando una pantalla en la que "no pasó nada". Ese contraste entre fallar ruidosamente y fallar en silencio es algo a lo que vas a volver todo el semestre.
Ejemplos de Código
3 ejemplos
El App.js que trae Snack
1import { StyleSheet, Text, View } from "react-native";
2
3export default function App() {
4 return (
5 <View style={styles.container}>
6 <Text>Open up App.js to start working on your app!</Text>
7 </View>
8 );
9}
10
11const styles = StyleSheet.create({
12 container: {
13 flex: 1,
14 alignItems: "center",
15 justifyContent: "center",
16 },
17});Texto con estilos propios
1<View style={styles.container}>
2 <Text style={styles.titulo}>Hola, soy Nombre</Text>
3 <Text style={styles.sub}>Mi primera app móvil</Text>
4</View>
5
6const styles = StyleSheet.create({
7 container: {
8 flex: 1,
9 alignItems: "center",
10 justifyContent: "center",
11 },
12 titulo: { fontSize: 28, fontWeight: "bold", marginBottom: 8 },
13 sub: { fontSize: 16, color: "#666" },
14});Un botón con estado
1import { useState } from "react";
2import { Pressable, Text, View, StyleSheet } from "react-native";
3
4export default function App() {
5 const [conteo, setConteo] = useState(0);
6
7 return (
8 <View style={styles.container}>
9 <Pressable
10 style={styles.boton}
11 onPress={() => setConteo(conteo + 1)}
12 >
13 <Text style={styles.textoBoton}>Presióname ({conteo})</Text>
14 </Pressable>
15 </View>
16 );
17}
18
19const styles = StyleSheet.create({
20 container: { flex: 1, alignItems: "center", justifyContent: "center" },
21 boton: { backgroundColor: "#007AFF", padding: 15, borderRadius: 8 },
22 textoBoton: { color: "#fff", fontSize: 16, fontWeight: "bold" },
23});Recursos
4 recursos disponibles
Documentación Oficial
Expo Snack
El editor de React Native que corre en el navegador. No necesitas cuenta para trabajar.
Documentación Oficial
Expo Go
La app que ejecuta tu Snack en tu teléfono. Instálala antes de la sesión.
¡Hora de Practicar!
Práctica Guiada — Tu primera pantalla
Cinco pasos para pasar del Snack vacío a una pantalla con estilos y un botón que responde, corriendo en tu teléfono.
Trabaja directo en snack.expo.dev. No instales nada todavía.
- Lee antes de tocar. Abre
App.jse identifica tres cosas: de dónde vienen los imports, cuál es el componente y dónde está el objeto de estilos. Si no puedes señalarlas, no sigas. - Cambia el texto. Sustituye el
<Text>por tu nombre y agrega un segundo<Text>como subtítulo, cada uno con su estilo. - Agrega un botón de verdad. Un
<Pressable>cononPressque incremente un contador conuseState. - Córrelo en tu teléfono. Pestaña My Device, escanea el QR con Expo Go. Tu teléfono y tu computadora deben estar en la misma red.
- Comparte. Botón Share > Copy link. Verifica que el link abra sin iniciar sesión.
Entrega: el link de tu Snack + tu bitácora de IA si la usaste. Opcional pero recomendado: una captura de tu teléfono con la app corriendo.
Desafío de Código
Ejercicios — Rómpelo a propósito
Cuatro errores que vas a cometer sin querer durante el semestre. Provócalos hoy, con red de seguridad.
Haz cada cambio, observa qué pasa exactamente y escribe el mensaje de error o el comportamiento que viste. Después deshazlo.
- Escribe texto suelto dentro del
<View>, fuera de cualquier<Text>. ¿Qué dice el error? - Cambia
fontSize: 28porfontSize: "28px". ¿Truena, se ignora o se ve raro? - Borra el
importdePressabley deja el componente usándolo. ¿En qué momento te enteras del problema? - Agrega
<Image source={{ uri: "https://picsum.photos/400" }} />sinwidthniheight. ¿Dónde quedó la imagen?
La pregunta que amarra las cuatro: ¿cuáles fallan con un error ruidoso y cuáles fallan en silencio? Las silenciosas son las que te van a costar horas más adelante.