Primera App y Componentes Básicos
Volver a clases
Desarrollo MóvilPrincipiante

Primera App y Componentes Básicos

120 min

Creación de la primera app, uso de componentes y estilos básicos en React Native.

App.js Básica

javascript
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
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

javascript
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}
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

javascript
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

javascript
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

javascript
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

EjercicioPrincipiante🔴 Sin IA

Ejercicios

  1. Modificar colores: Cambia el esquema de colores de la tarjeta.
  2. Agregar estado: Añade un contador de visitas.
  3. Más botones: Agrega GitHub, Twitter, Portfolio.
  4. Animación básica: Haz que el avatar tenga un efecto al presionar.

Documentación Oficial

DocumentaciónPrincipiante30 min

Documentacion util

¡Hora de Practicar!

PrácticaPrincipiante30 min🟡 IA con bitácora

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 LecturaPrincipiante30 min🔴 Sin IA

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.

jsx
1import { 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?