En este proyecto, vamos a construir una aplicación de chat en tiempo real 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 el almacenamiento local.

Objetivos del Proyecto

  • Crear una interfaz de usuario para una aplicación de chat.
  • Implementar la navegación entre pantallas.
  • Manejar el estado de la aplicación y el ciclo de vida de los componentes.
  • Integrar con una API de chat en tiempo real.
  • Almacenar mensajes localmente para acceso offline.

Requisitos Previos

Antes de comenzar, asegúrate de tener:

  • Un entorno de desarrollo configurado para React Native.
  • Conocimientos básicos de React Native, incluyendo componentes, estado y navegación.
  • Familiaridad con la Fetch API o Axios para realizar solicitudes HTTP.

Estructura del Proyecto

El proyecto se dividirá en las siguientes secciones:

  1. Configuración del Proyecto
  2. Creación de la Interfaz de Usuario
  3. Implementación de la Navegación
  4. Manejo del Estado y Ciclo de Vida
  5. Integración con la API de Chat
  6. Almacenamiento Local de Mensajes
  7. Pruebas y Depuración

  1. Configuración del Proyecto

Paso 1: Crear un Nuevo Proyecto

Primero, crea un nuevo proyecto de React Native:

npx react-native init ChatApp
cd ChatApp

Paso 2: Instalar Dependencias Necesarias

Instala las dependencias necesarias para la navegación y la integración con la API de chat:

npm install @react-navigation/native @react-navigation/stack
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

Paso 3: Configurar la Navegación

Configura la navegación en tu proyecto:

// App.js
import 'react-native-gesture-handler';
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import ChatScreen from './screens/ChatScreen';
import LoginScreen from './screens/LoginScreen';

const Stack = createStackNavigator();

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

  1. Creación de la Interfaz de Usuario

Pantalla de Inicio de Sesión

Crea una pantalla de inicio de sesión simple:

// screens/LoginScreen.js
import React, { useState } from 'react';
import { View, Text, TextInput, Button, StyleSheet } from 'react-native';

export default function LoginScreen({ navigation }) {
  const [username, setUsername] = useState('');

  const handleLogin = () => {
    navigation.navigate('Chat', { username });
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Login</Text>
      <TextInput
        style={styles.input}
        placeholder="Enter your username"
        value={username}
        onChangeText={setUsername}
      />
      <Button title="Login" onPress={handleLogin} />
    </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: 16,
    paddingHorizontal: 8,
  },
});

Pantalla de Chat

Crea una pantalla de chat básica:

// screens/ChatScreen.js
import React, { useState, useEffect } from 'react';
import { View, Text, TextInput, Button, FlatList, StyleSheet } from 'react-native';
import axios from 'axios';

export default function ChatScreen({ route }) {
  const { username } = route.params;
  const [message, setMessage] = useState('');
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    // Aquí puedes agregar la lógica para obtener mensajes desde la API
  }, []);

  const sendMessage = () => {
    const newMessage = { username, text: message };
    setMessages([...messages, newMessage]);
    setMessage('');
    // Aquí puedes agregar la lógica para enviar el mensaje a la API
  };

  return (
    <View style={styles.container}>
      <FlatList
        data={messages}
        renderItem={({ item }) => (
          <View style={styles.message}>
            <Text style={styles.username}>{item.username}</Text>
            <Text>{item.text}</Text>
          </View>
        )}
        keyExtractor={(item, index) => index.toString()}
      />
      <TextInput
        style={styles.input}
        placeholder="Type a message"
        value={message}
        onChangeText={setMessage}
      />
      <Button title="Send" onPress={sendMessage} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  message: {
    marginBottom: 16,
  },
  username: {
    fontWeight: 'bold',
  },
  input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    marginBottom: 16,
    paddingHorizontal: 8,
  },
});

  1. Implementación de la Navegación

Ya hemos configurado la navegación en el paso anterior. Asegúrate de que las pantallas LoginScreen y ChatScreen estén correctamente importadas y configuradas en App.js.

  1. Manejo del Estado y Ciclo de Vida

Utiliza useState y useEffect para manejar el estado y el ciclo de vida de los componentes. En este caso, useEffect se utiliza para obtener mensajes cuando la pantalla de chat se monta.

  1. Integración con la API de Chat

Para integrar con una API de chat en tiempo real, puedes usar servicios como Firebase o Socket.io. Aquí hay un ejemplo básico usando Firebase:

Configuración de Firebase

Primero, instala Firebase:

npm install @react-native-firebase/app @react-native-firebase/firestore

Luego, configura Firebase en tu proyecto:

// firebase.js
import firebase from '@react-native-firebase/app';
import firestore from '@react-native-firebase/firestore';

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID"
};

if (!firebase.apps.length) {
  firebase.initializeApp(firebaseConfig);
}

export { firebase, firestore };

Obtener y Enviar Mensajes

Actualiza ChatScreen para obtener y enviar mensajes usando Firebase Firestore:

// screens/ChatScreen.js
import React, { useState, useEffect } from 'react';
import { View, Text, TextInput, Button, FlatList, StyleSheet } from 'react-native';
import { firestore } from '../firebase';

export default function ChatScreen({ route }) {
  const { username } = route.params;
  const [message, setMessage] = useState('');
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    const unsubscribe = firestore()
      .collection('messages')
      .orderBy('createdAt', 'desc')
      .onSnapshot(querySnapshot => {
        const messages = querySnapshot.docs.map(doc => ({
          _id: doc.id,
          ...doc.data(),
        }));
        setMessages(messages);
      });

    return () => unsubscribe();
  }, []);

  const sendMessage = () => {
    firestore().collection('messages').add({
      text: message,
      username,
      createdAt: new Date().getTime(),
    });
    setMessage('');
  };

  return (
    <View style={styles.container}>
      <FlatList
        data={messages}
        renderItem={({ item }) => (
          <View style={styles.message}>
            <Text style={styles.username}>{item.username}</Text>
            <Text>{item.text}</Text>
          </View>
        )}
        keyExtractor={(item) => item._id}
        inverted
      />
      <TextInput
        style={styles.input}
        placeholder="Type a message"
        value={message}
        onChangeText={setMessage}
      />
      <Button title="Send" onPress={sendMessage} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  message: {
    marginBottom: 16,
  },
  username: {
    fontWeight: 'bold',
  },
  input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    marginBottom: 16,
    paddingHorizontal: 8,
  },
});

  1. Almacenamiento Local de Mensajes

Para almacenar mensajes localmente, puedes usar AsyncStorage. Aquí hay un ejemplo básico:

npm install @react-native-async-storage/async-storage

Luego, actualiza ChatScreen para almacenar y recuperar mensajes localmente:

// screens/ChatScreen.js
import React, { useState, useEffect } from 'react';
import { View, Text, TextInput, Button, FlatList, StyleSheet, AsyncStorage } from 'react-native';
import { firestore } from '../firebase';

export default function ChatScreen({ route }) {
  const { username } = route.params;
  const [message, setMessage] = useState('');
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    const loadMessages = async () => {
      const storedMessages = await AsyncStorage.getItem('messages');
      if (storedMessages) {
        setMessages(JSON.parse(storedMessages));
      }
    };

    loadMessages();

    const unsubscribe = firestore()
      .collection('messages')
      .orderBy('createdAt', 'desc')
      .onSnapshot(querySnapshot => {
        const messages = querySnapshot.docs.map(doc => ({
          _id: doc.id,
          ...doc.data(),
        }));
        setMessages(messages);
        AsyncStorage.setItem('messages', JSON.stringify(messages));
      });

    return () => unsubscribe();
  }, []);

  const sendMessage = () => {
    firestore().collection('messages').add({
      text: message,
      username,
      createdAt: new Date().getTime(),
    });
    setMessage('');
  };

  return (
    <View style={styles.container}>
      <FlatList
        data={messages}
        renderItem={({ item }) => (
          <View style={styles.message}>
            <Text style={styles.username}>{item.username}</Text>
            <Text>{item.text}</Text>
          </View>
        )}
        keyExtractor={(item) => item._id}
        inverted
      />
      <TextInput
        style={styles.input}
        placeholder="Type a message"
        value={message}
        onChangeText={setMessage}
      />
      <Button title="Send" onPress={sendMessage} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  message: {
    marginBottom: 16,
  },
  username: {
    fontWeight: 'bold',
  },
  input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    marginBottom: 16,
    paddingHorizontal: 8,
  },
});

  1. Pruebas y Depuración

Finalmente, asegúrate de probar tu aplicación en diferentes dispositivos y escenarios. Utiliza herramientas de depuración como React Native Debugger y Reactotron para identificar y solucionar problemas.

Conclusión

En este proyecto, hemos construido una aplicación de chat en tiempo real utilizando React Native. Hemos cubierto la creación de la interfaz de usuario, la implementación de la navegación, el manejo del estado y el ciclo de vida, la integración con una API de chat y el almacenamiento local de mensajes. Este proyecto te proporciona una base sólida para construir aplicaciones de chat más complejas y personalizadas en el futuro.

© Copyright 2024. Todos los derechos reservados