Aplicación web Full Stack para la gestión de notas personales. Permite crear, leer, actualizar, eliminar y buscar notas en tiempo real.
Autor: Pereyra Roman, Ramiro
| Capa | Stack |
|---|---|
| Frontend | React + Vite + TypeScript |
| Backend | Express + TypeScript |
| Base de Datos | MongoDB (Mongoose) |
tp-react-native/
├── backend/
│ └── src/
│ ├── config/ # Conexión a MongoDB
│ ├── controllers/ # Lógica de los endpoints
│ ├── models/ # Esquema de Mongoose (Nota)
│ ├── routes/ # Definición de rutas
│ └── app.ts # Punto de entrada del servidor
├── frontend/
│ └── src/
│ ├── components/ # NotaForm, NotaList, NotaItem, FiltroNotas
│ ├── services/ # Consumo de la API (fetch + async/await)
│ ├── types/ # Interfaces TypeScript
│ └── App.tsx # Componente principal
└── README.md
git clone https://github.com/ramirorn/tp2-react-native.git
cd tp2-react-nativecd backend
npm installCrear un archivo .env en la carpeta backend/ con el siguiente contenido:
MONGODB_URI=tu_cadena_de_conexion_a_mongodbIniciar el servidor:
npm run build
npm run devEl backend estará disponible en http://localhost:3000.
cd frontend
npm install
npm run devEl frontend estará disponible en http://localhost:5173.
Base URL: http://localhost:3000/api/notas
GET /api/notas
Respuesta exitosa (200):
[
{
"_id": "663f...",
"titulo": "Mi primera nota",
"contenido": "Contenido de ejemplo",
"createdAt": "2026-04-11T...",
"updatedAt": "2026-04-11T..."
}
]GET /api/notas/:id
Respuesta exitosa (200):
{
"_id": "663f...",
"titulo": "Mi primera nota",
"contenido": "Contenido de ejemplo",
"createdAt": "2026-04-11T...",
"updatedAt": "2026-04-11T..."
}Error (404):
{ "mensaje": "Nota no encontrada" }POST /api/notas
Content-Type: application/json
Body:
{
"titulo": "Nueva nota",
"contenido": "Descripción de la nota"
}Respuesta exitosa (201): Retorna la nota creada.
Error (400): Si faltan campos obligatorios:
{ "mensaje": "Faltan campos obligatorios" }PUT /api/notas/:id
Content-Type: application/json
Body:
{
"titulo": "Título actualizado",
"contenido": "Contenido actualizado"
}Respuesta exitosa (200): Retorna la nota actualizada.
Error (400): Si faltan campos obligatorios.
Error (404): Si la nota no existe.
DELETE /api/notas/:id
Respuesta exitosa (200):
{ "mensaje": "Nota eliminada" }Error (404): Si la nota no existe:
{ "mensaje": "Nota no encontrada" }- Visualización de todas las notas
- Creación de notas con validación de campos
- Edición de notas existentes
- Eliminación de notas
- Búsqueda/filtrado en tiempo real por título o contenido
- Estados de carga y manejo de errores
useState es un hook que permite declarar variables de estado dentro de un componente funcional. Cada vez que el estado cambia, React vuelve a renderizar el componente para reflejar los nuevos datos en la interfaz.
¿Dónde se usa y por qué?
| Componente | Estado | Justificación |
|---|---|---|
App.tsx |
notas |
Almacena el arreglo de notas obtenidas desde la API. Es el estado central de la aplicación; al modificarlo (crear, editar, eliminar), la lista se actualiza automáticamente. |
App.tsx |
cargando |
Controla si se muestra el indicador de carga mientras se espera la respuesta del servidor. Mejora la experiencia del usuario al dar feedback visual. |
App.tsx |
error |
Almacena mensajes de error provenientes de la API o de fallos de red. Permite mostrar un banner informativo cuando algo sale mal. |
App.tsx |
busqueda |
Guarda el texto ingresado en el campo de búsqueda. Se usa para filtrar las notas en tiempo real sin necesidad de hacer una nueva consulta al servidor. |
App.tsx |
notaEditar |
Indica si se está editando una nota existente (Nota) o creando una nueva (null). Permite que el formulario cambie dinámicamente entre modo creación y modo edición. |
NotaForm.tsx |
titulo, contenido |
Controlan los valores de los campos del formulario de manera individual, permitiendo validación en tiempo real y limpieza al enviar. |
NotaForm.tsx |
enviando |
Deshabilita el botón de envío y muestra "Guardando..." mientras la petición está en curso, evitando envíos duplicados. |
Ejemplo de uso en el proyecto:
const [notas, setNotas] = useState<Nota[]>([]);
const [cargando, setCargando] = useState(true);
const [error, setError] = useState<string | null>(null);useEffect es un hook que permite ejecutar efectos secundarios en componentes funcionales. Se utiliza para operaciones que no forman parte del renderizado, como llamadas a APIs, suscripciones o manipulación del DOM.
¿Dónde se usa y por qué?
Se utiliza en App.tsx para cargar las notas desde la API al montar el componente por primera vez:
useEffect(() => {
cargarNotas();
}, []);Justificación:
- El arreglo de dependencias vacío (
[]) asegura que la funcióncargarNotas()se ejecute una sola vez cuando el componente se monta en el DOM. - Sin
useEffect, la llamada a la API se ejecutaría en cada renderizado, generando un bucle infinito de peticiones. - Este patrón es el estándar en React para la carga inicial de datos desde un servidor.
Flujo completo:
- El componente
Appse monta →useEffectse dispara. - Se llama a
cargarNotas()que establececargando = true. - Se hace
fetchaGET /api/notas. - Se reciben los datos y se guardan en el estado
notasconsetNotas(data). - Se establece
cargando = false→ la interfaz muestra la lista de notas. - Si ocurre un error, se captura y se guarda en el estado
errorpara mostrarlo al usuario.