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:

jsx
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:

jsx
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:

  • useState es un Hook de React que nos permite manejar estado en componentes funcionales

  • movie contendrá los datos de la película que estamos creando

  • setMovie es la función para actualizar el estado de la película

  • submitted nos indica si la película fue creada exitosamente

  • setSubmitted actualiza el estado de submitted

Paso 3: Manejador de cambios en el formulario

jsx
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 name y value del evento

  • Spread operator (...) copia todas las propiedades actuales de movie

  • [name]: value actualiza dinámicamente la propiedad correspondiente

Paso 4: Método para guardar la película

jsx
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/await maneja operaciones asíncronas de forma limpia

  • El 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

jsx
const newMovie = () => {
  // Restablecemos el estado inicial
  setMovie(initialMovieState);
  setSubmitted(false);
};

Paso 6: Estructura del formulario (JSX)

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)

css
.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:

  1. Maneja estado local con useState

  2. Controla inputs con manejo de eventos

  3. Se comunica con el backend mediante servicios

  4. Proporciona feedback al usuario sobre el estado de la operación

  5. 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

Entradas más populares de este blog

Axios para Principiantes - Guía Paso a Paso

Tutorial de React para Principiantes