15-Tutorial: Crear Película en React con useState
Introducción
¡Excelente! Ya tienes todos los métodos configurados para conectar tu aplicación React con el backend. Ahora vamos a implementar la funcionalidad para crear películas, lo que nos permitirá tener una lista inicial de películas al regresar al home.
Paso 1: Importaciones necesarias
Vamos al componente AddMovie.js y realizamos las importaciones:
import React, { useState } from 'react';
import MovieService from '../services/movieService';Paso 2: Estado inicial de la película
Dentro del componente funcional, antes del return, definimos el estado inicial:
const AddMovie = () => {
// Estado inicial de la película
const initialMovieState = {
title: '',
director: '',
genre: '',
synopsis: '',
year: 0,
rating: 0
};
// Estado para manejar la película actual
const [movie, setMovie] = useState(initialMovieState);
// Estado para controlar si la película fue creada
const [submitted, setSubmitted] = useState(false);
// Resto del código...
};Explicación:
useStatees un Hook de React que nos permite manejar estado en componentes funcionalesmoviecontendrá los datos de la película que estamos creandosetMoviees la función para actualizar el estado de la películasubmittednos indica si la película fue creada exitosamentesetSubmittedactualiza el estado de submitted
Paso 3: Manejador de cambios en el formulario
const handleInputChange = (event) => {
const { name, value } = event.target;
setMovie({
...movie, // Mantenemos todos los valores actuales
[name]: value // Actualizamos solo el campo que cambió
});
};Explicación:
Usamos destructuración para obtener
nameyvaluedel eventoSpread operator (
...) copia todas las propiedades actuales demovie[name]: valueactualiza dinámicamente la propiedad correspondiente
Paso 4: Método para guardar la película
const saveMovie = async () => {
try {
// Preparamos los datos para enviar
const data = {
title: movie.title,
director: movie.director,
genre: movie.genre,
synopsis: movie.synopsis,
year: movie.year,
rating: movie.rating
};
// Llamamos al servicio para crear la película
const response = await MovieService.create(data);
// Actualizamos el estado con la respuesta del servidor
setMovie(response.data);
// Indicamos que la película fue creada
setSubmitted(true);
console.log('Película creada:', response.data);
} catch (error) {
console.error('Ocurrió un error al crear la película:', error);
alert('Ocurrió un error al guardar la película');
}
};Explicación:
async/awaitmaneja operaciones asíncronas de forma limpiaEl servidor responde con datos completos (incluyendo ID y timestamps)
Actualizamos el estado local con la respuesta del servidor
Manejamos errores con
try-catch
Paso 5: Método para resetear el formulario
const newMovie = () => {
// Restablecemos el estado inicial
setMovie(initialMovieState);
setSubmitted(false);
};Paso 6: Estructura del formulario (JSX)
return (
<div className="submit-form">
{submitted ? (
<div>
<h4>¡Película creada exitosamente!</h4>
<button className="btn btn-success" onClick={newMovie}>
Agregar otra película
</button>
</div>
) : (
<div>
<h2>Crear Nueva Película</h2>
<div className="form-group">
<label htmlFor="title">Título</label>
<input
type="text"
className="form-control"
id="title"
name="title"
value={movie.title}
onChange={handleInputChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="director">Director</label>
<input
type="text"
className="form-control"
id="director"
name="director"
value={movie.director}
onChange={handleInputChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="genre">Género</label>
<input
type="text"
className="form-control"
id="genre"
name="genre"
value={movie.genre}
onChange={handleInputChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="year">Año</label>
<input
type="number"
className="form-control"
id="year"
name="year"
value={movie.year}
onChange={handleInputChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="synopsis">Sinopsis</label>
<textarea
className="form-control"
id="synopsis"
name="synopsis"
value={movie.synopsis}
onChange={handleInputChange}
rows="3"
required
/>
</div>
<button onClick={saveMovie} className="btn btn-primary">
Guardar Película
</button>
</div>
)}
</div>
);Paso 7: Estilos CSS (opcional)
.submit-form {
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.form-control {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.btn {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
margin-top: 10px;
}
.btn-primary {
background-color: #007bff;
color: white;
}
.btn-success {
background-color: #28a745;
color: white;
}Resumen
Hemos creado un componente completo para agregar películas que:
Maneja estado local con
useStateControla inputs con manejo de eventos
Se comunica con el backend mediante servicios
Proporciona feedback al usuario sobre el estado de la operación
Permite agregar múltiples películas sin recargar la página
Próximos pasos
En la siguiente clase implementaremos:
Validación de formularios
Mensajes de error más específicos
Redirección automática después de crear una película
Integración con el listado general de películas
Consejo: Asegúrate de que tu servicio MovieService.create() esté correctamente configurado para hacer peticiones POST a tu endpoint del backend.
Comentarios
Publicar un comentario