En este proyecto, vamos a construir una aplicación de redes sociales utilizando React Native. Este proyecto integrará muchos de los conceptos que hemos aprendido a lo largo del curso, incluyendo la navegación, el manejo de estado, la integración con APIs, y más.

Objetivos del Proyecto

  • Crear una interfaz de usuario atractiva y funcional.
  • Implementar la navegación entre diferentes pantallas.
  • Manejar el estado de la aplicación y las interacciones del usuario.
  • Integrar con una API para obtener y enviar datos.
  • Implementar características comunes de una red social como publicaciones, comentarios y likes.

Estructura del Proyecto

  1. Configuración Inicial
  2. Pantalla de Inicio de Sesión
  3. Pantalla de Registro
  4. Pantalla de Feed
  5. Pantalla de Perfil
  6. Pantalla de Publicación
  7. Integración con API
  8. Manejo de Estado y Contexto
  9. Estilizado y Animaciones
  10. Pruebas y Depuración

  1. Configuración Inicial

Crear el Proyecto

Primero, creamos un nuevo proyecto de React Native:

npx react-native init SocialMediaApp
cd SocialMediaApp

Instalar Dependencias Necesarias

Instalamos las dependencias necesarias para la navegación y el manejo de estado:

npm install @react-navigation/native @react-navigation/stack @react-navigation/bottom-tabs
npm install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
npm install axios

Configuración de la Navegación

Configuramos la navegación en App.js:

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import LoginScreen from './screens/LoginScreen';
import RegisterScreen from './screens/RegisterScreen';
import FeedScreen from './screens/FeedScreen';
import ProfileScreen from './screens/ProfileScreen';
import PostScreen from './screens/PostScreen';

const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();

function MainTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Feed" component={FeedScreen} />
      <Tab.Screen name="Profile" component={ProfileScreen} />
      <Tab.Screen name="Post" component={PostScreen} />
    </Tab.Navigator>
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Login">
        <Stack.Screen name="Login" component={LoginScreen} />
        <Stack.Screen name="Register" component={RegisterScreen} />
        <Stack.Screen name="Main" component={MainTabs} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

  1. Pantalla de Inicio de Sesión

Crear el Componente LoginScreen

Creamos un archivo LoginScreen.js en la carpeta screens:

import React, { useState } from 'react';
import { View, Text, TextInput, Button, StyleSheet } from 'react-native';

export default function LoginScreen({ navigation }) {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleLogin = () => {
    // Lógica de autenticación
    navigation.navigate('Main');
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Iniciar Sesión</Text>
      <TextInput
        style={styles.input}
        placeholder="Email"
        value={email}
        onChangeText={setEmail}
      />
      <TextInput
        style={styles.input}
        placeholder="Contraseña"
        value={password}
        onChangeText={setPassword}
        secureTextEntry
      />
      <Button title="Iniciar Sesión" onPress={handleLogin} />
      <Button title="Registrarse" onPress={() => navigation.navigate('Register')} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    padding: 16,
  },
  title: {
    fontSize: 24,
    marginBottom: 16,
    textAlign: 'center',
  },
  input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    marginBottom: 12,
    paddingHorizontal: 8,
  },
});

  1. Pantalla de Registro

Crear el Componente RegisterScreen

Creamos un archivo RegisterScreen.js en la carpeta screens:

import React, { useState } from 'react';
import { View, Text, TextInput, Button, StyleSheet } from 'react-native';

export default function RegisterScreen({ navigation }) {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');

  const handleRegister = () => {
    // Lógica de registro
    navigation.navigate('Login');
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Registrarse</Text>
      <TextInput
        style={styles.input}
        placeholder="Email"
        value={email}
        onChangeText={setEmail}
      />
      <TextInput
        style={styles.input}
        placeholder="Contraseña"
        value={password}
        onChangeText={setPassword}
        secureTextEntry
      />
      <TextInput
        style={styles.input}
        placeholder="Confirmar Contraseña"
        value={confirmPassword}
        onChangeText={setConfirmPassword}
        secureTextEntry
      />
      <Button title="Registrarse" onPress={handleRegister} />
      <Button title="Volver a Iniciar Sesión" onPress={() => navigation.navigate('Login')} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    padding: 16,
  },
  title: {
    fontSize: 24,
    marginBottom: 16,
    textAlign: 'center',
  },
  input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    marginBottom: 12,
    paddingHorizontal: 8,
  },
});

  1. Pantalla de Feed

Crear el Componente FeedScreen

Creamos un archivo FeedScreen.js en la carpeta screens:

import React, { useState, useEffect } from 'react';
import { View, Text, FlatList, StyleSheet } from 'react-native';
import axios from 'axios';

export default function FeedScreen() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    axios.get('https://api.example.com/posts')
      .then(response => setPosts(response.data))
      .catch(error => console.error(error));
  }, []);

  const renderItem = ({ item }) => (
    <View style={styles.post}>
      <Text style={styles.postTitle}>{item.title}</Text>
      <Text>{item.body}</Text>
    </View>
  );

  return (
    <View style={styles.container}>
      <FlatList
        data={posts}
        renderItem={renderItem}
        keyExtractor={item => item.id.toString()}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  post: {
    marginBottom: 16,
    padding: 16,
    backgroundColor: '#fff',
    borderRadius: 8,
    shadowColor: '#000',
    shadowOpacity: 0.1,
    shadowRadius: 10,
    elevation: 5,
  },
  postTitle: {
    fontSize: 18,
    fontWeight: 'bold',
    marginBottom: 8,
  },
});

  1. Pantalla de Perfil

Crear el Componente ProfileScreen

Creamos un archivo ProfileScreen.js en la carpeta screens:

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

export default function ProfileScreen() {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Perfil del Usuario</Text>
      {/* Información del perfil del usuario */}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  title: {
    fontSize: 24,
    marginBottom: 16,
  },
});

  1. Pantalla de Publicación

Crear el Componente PostScreen

Creamos un archivo PostScreen.js en la carpeta screens:

import React, { useState } from 'react';
import { View, Text, TextInput, Button, StyleSheet } from 'react-native';
import axios from 'axios';

export default function PostScreen() {
  const [title, setTitle] = useState('');
  const [body, setBody] = useState('');

  const handlePost = () => {
    axios.post('https://api.example.com/posts', { title, body })
      .then(response => {
        setTitle('');
        setBody('');
        alert('Publicación exitosa');
      })
      .catch(error => console.error(error));
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Nueva Publicación</Text>
      <TextInput
        style={styles.input}
        placeholder="Título"
        value={title}
        onChangeText={setTitle}
      />
      <TextInput
        style={styles.input}
        placeholder="Contenido"
        value={body}
        onChangeText={setBody}
        multiline
      />
      <Button title="Publicar" onPress={handlePost} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  title: {
    fontSize: 24,
    marginBottom: 16,
    textAlign: 'center',
  },
  input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    marginBottom: 12,
    paddingHorizontal: 8,
  },
});

  1. Integración con API

Configuración de Axios

Creamos un archivo api.js para configurar Axios:

import axios from 'axios';

const api = axios.create({
  baseURL: 'https://api.example.com',
});

export default api;

Uso de Axios en Componentes

Actualizamos los componentes para usar la configuración de Axios:

import api from '../api';

// Ejemplo en FeedScreen
useEffect(() => {
  api.get('/posts')
    .then(response => setPosts(response.data))
    .catch(error => console.error(error));
}, []);

  1. Manejo de Estado y Contexto

Crear el Contexto de Usuario

Creamos un archivo UserContext.js:

import React, { createContext, useState } from 'react';

export const UserContext = createContext();

export const UserProvider = ({ children }) => {
  const [user, setUser] = useState(null);

  return (
    <UserContext.Provider value={{ user, setUser }}>
      {children}
    </UserContext.Provider>
  );
};

Usar el Contexto en App.js

Actualizamos App.js para usar el contexto:

import { UserProvider } from './UserContext';

export default function App() {
  return (
    <UserProvider>
      <NavigationContainer>
        <Stack.Navigator initialRouteName="Login">
          <Stack.Screen name="Login" component={LoginScreen} />
          <Stack.Screen name="Register" component={RegisterScreen} />
          <Stack.Screen name="Main" component={MainTabs} />
        </Stack.Navigator>
      </NavigationContainer>
    </UserProvider>
  );
}

  1. Estilizado y Animaciones

Estilizado

Usamos StyleSheet para estilizar los componentes, como se ha mostrado en los ejemplos anteriores.

Animaciones

Podemos usar la librería react-native-reanimated para agregar animaciones. Aquí hay un ejemplo simple:

import Animated from 'react-native-reanimated';

const AnimatedView = Animated.createAnimatedComponent(View);

export default function AnimatedComponent() {
  const opacity = new Animated.Value(0);

  useEffect(() => {
    Animated.timing(opacity, {
      toValue: 1,
      duration: 1000,
    }).start();
  }, []);

  return (
    <AnimatedView style={{ ...styles.container, opacity }}>
      <Text>Animación de ejemplo</Text>
    </AnimatedView>
  );
}

  1. Pruebas y Depuración

Pruebas

Podemos usar jest y react-native-testing-library para escribir pruebas unitarias y de integración.

Depuración

Usamos herramientas como Reactotron o las herramientas de desarrollo de React Native para depurar la aplicación.

Conclusión

En este proyecto, hemos construido una aplicación de redes sociales completa utilizando React Native. Hemos cubierto la configuración inicial, la creación de pantallas, la integración con una API, el manejo de estado y contexto, el estilizado y las animaciones, y las pruebas y depuración. Este proyecto debería darte una buena base para construir aplicaciones móviles complejas y funcionales con React Native. ¡Sigue practicando y explorando más características avanzadas para mejorar tus habilidades!

© Copyright 2024. Todos los derechos reservados