Creación de la primera app, uso de componentes y estilos básicos en React Native.
App.js Básica
javascript1import { StatusBar } from "expo-status-bar"; 2import { StyleSheet, Text, View, Button, Alert } from "react-native"; 3import { useState } from "react"; 4 5export default function App() { 6 const [count, setCount] = useState(0); 7 8 const handlePress = () => { 9 setCount(count + 1); 10 Alert.alert("¡Presionado!", `Has presionado ${count + 1} veces`); 11 }; 12 13 return ( 14 <View style={styles.container}> 15 <Text style={styles.title}>Mi Primera App</Text> 16 <Text style={styles.subtitle}>Contador: {count}</Text> 17 <Button title="Incrementar" onPress={handlePress} color="#841584" /> 18 <StatusBar style="auto" /> 19 </View> 20 ); 21} 22 23const styles = StyleSheet.create({ 24 container: { 25 flex: 1, 26 backgroundColor: "#fff", 27 alignItems: "center", 28 justifyContent: "center", 29 padding: 20, 30 }, 31 title: { 32 fontSize: 28, 33 fontWeight: "bold", 34 marginBottom: 20, 35 color: "#333", 36 }, 37 subtitle: { 38 fontSize: 18, 39 marginBottom: 30, 40 color: "#666", 41 }, 42});
TouchableOpacity vs Button
javascript1import { TouchableOpacity, Text, StyleSheet } from "react-native"; 2 3function CustomButton() { 4 return ( 5 <TouchableOpacity 6 style={styles.button} 7 onPress={() => console.log("Presionado")} 8 activeOpacity={0.7} 9 > 10 <Text style={styles.buttonText}>Botón Personalizado</Text> 11 </TouchableOpacity> 12 ); 13} 14 15const styles = StyleSheet.create({ 16 button: { 17 backgroundColor: "#007AFF", 18 padding: 15, 19 borderRadius: 8, 20 marginTop: 20, 21 }, 22 buttonText: { 23 color: "white", 24 fontSize: 16, 25 fontWeight: "600", 26 textAlign: "center", 27 }, 28});
Ejemplos de Código
3 ejemplos
App.js Básica
1import { StatusBar } from "expo-status-bar";
2import { StyleSheet, Text, View, Button, Alert } from "react-native";
3import { useState } from "react";
4
5export default function App() {
6 const [count, setCount] = useState(0);
7 const handlePress = () => {
8 setCount(count + 1);
9 Alert.alert("¡Presionado!", `Has presionado ${count + 1} veces`);
10 };
11 return (
12 <View style={styles.container}>
13 <Text style={styles.title}>Mi Primera App</Text>
14 <Text style={styles.subtitle}>Contador: {count}</Text>
15 <Button title="Incrementar" onPress={handlePress} color="#841584" />
16 <StatusBar style="auto" />
17 </View>
18 );
19}Botón Personalizado
1import { TouchableOpacity, Text, StyleSheet } from "react-native";
2
3function CustomButton() {
4 return (
5 <TouchableOpacity
6 style={styles.button}
7 onPress={() => console.log("Presionado")}
8 activeOpacity={0.7}
9 >
10 <Text style={styles.buttonText}>Botón Personalizado</Text>
11 </TouchableOpacity>
12 );
13}Tarjeta de Presentación
1import {
2 View,
3 Text,
4 Image,
5 TouchableOpacity,
6 Linking,
7 StyleSheet,
8} from "react-native";
9
10export default function BusinessCard() {
11 const openLink = (url) => {
12 Linking.openURL(url);
13 };
14
15 return (
16 <View style={styles.container}>
17 <Image
18 source={{ uri: "https://via.placeholder.com/150" }}
19 style={styles.avatar}
20 />
21 <Text style={styles.name}>Juan Pérez</Text>
22 <Text style={styles.title}>Desarrollador Móvil</Text>
23 <Text style={styles.description}>
24 Especializado en React Native y experiencias móviles increíbles
25 </Text>
26 <View style={styles.buttonContainer}>
27 <TouchableOpacity
28 style={styles.button}
29 onPress={() => openLink("mailto:juan@example.com")}
30 >
31 <Text style={styles.buttonText}>📧 Email</Text>
32 </TouchableOpacity>
33 <TouchableOpacity
34 style={styles.button}
35 onPress={() => openLink("tel:+123456789")}
36 >
37 <Text style={styles.buttonText}>📱 Llamar</Text>
38 </TouchableOpacity>
39 <TouchableOpacity
40 style={styles.button}
41 onPress={() => openLink("https://linkedin.com/in/juanperez")}
42 >
43 <Text style={styles.buttonText}>💼 LinkedIn</Text>
44 </TouchableOpacity>
45 </View>
46 </View>
47 );
48}Recursos
4 recursos disponibles
Desafío de Código
Ejercicios
- Modificar colores: Cambia el esquema de colores de la tarjeta.
- Agregar estado: Añade un contador de visitas.
- Más botones: Agrega GitHub, Twitter, Portfolio.
- Animación básica: Haz que el avatar tenga un efecto al presionar.
Documentación Oficial
Documentacion util
- Expo Documentation
- React Native Docs
- Expo Snack - Playground online
- React Native Directory - Librerías
¡Hora de Practicar!
Tarjeta de Presentación
Proyecto de la semana
Crea una tarjeta de presentación interactiva con foto/avatar, nombre, título, descripción y botones de contacto (email, teléfono, LinkedIn). Personaliza los estilos y agrega animaciones simples si lo deseas.
Reto de Lectura
Reto de Lectura — La primera app que no compila
Cuatro errores de novato (y de IA) en una app mínima: dos truenan con mensajes crípticos, dos fallan en silencio. Diagnostícalos sin correr el código.
Esta app mínima tiene 4 problemas: dos lanzan errores con mensajes que no ayudan mucho, y dos fallan en silencio. Encuéntralos y explica el síntoma de cada uno.
jsx1import { View, Text, StyleSheet } from "react-native"; 2 3export default function App() { 4 const usuario = "Ana"; 5 return ( 6 <View style={styles.contenedor}> 7 Bienvenida a la app 8 <Text style={styles.titulo}>Hola, {usuario}</Text> 9 <View> 10 <Text style="titulo">Tu resumen de hoy</Text> 11 </View> 12 </View> 13 ); 14} 15 16const styles = StyleSheet.create({ 17 contenedor: { 18 backgroundColor: "#f5f5f5", 19 "justify-content": "center", 20 }, 21 titulo: { 22 fontSize: 22, 23 fontWeight: "bold", 24 }, 25});
Preguntas guía: ¿dónde puede vivir el texto en RN? ¿Qué formato tienen las propiedades de estilo? ¿Qué recibe la prop style? ¿Y por qué, aun corrigiendo todo, el contenido no queda centrado verticalmente?