DEV Community

Robert
Robert

Posted on • Edited on

creando una base de datos de películas con la API de OMDB y REACT

En el siguiente post aprenderemos a crear una aplicación muy básica y sencilla con React, donde integraremos la API de OMDB (https://www.omdbapi.com/), para obtener una key es sencillo, debes ingresar a la página, ir a la sección de API key, colocar el tipo de cuenta gratis, y colocar tu correo, unos momentos después recibirás la key en tu correo.

Puedes contactarme por telegram si necesitas contratar a un desarrollador Full Stack.

También puedes contactarme por discord Appu#9136

Creación del proyecto

  • abrir la terminal
  • ubicarnos en la carpeta donde vamos a querer crear nuestro proyecto
  • npx create-react-app react-omdb (o como desees nombrarlo)
  • cd react-omdb (o el nombre que le hayas colocado)
  • code .

El CSS que se usó para este ejemplo es muy sencillo, puedes copiarlo o descargarlo de este link (https://github.com/rtagliaviaz/react-omdb-tut/blob/main/src/App.css) o hacer tu propia interfaz si así lo deseas.

Estructura del proyecto:

react-omdb/
├── node_modules/
├── public/
├── src/
│ ├── components/
│ ├── App.css
│ ├── App.js
│ └── index.css
│ └── index.js
└── package.json

Dependencias

  • axios

Para este ejemplo solo instalaremos axios como dependencia adicional, lo haremos abriendo la consola ubicados en nuestro proyecto, seguido de npm i axios.

Finalmente para poder empezar, volveremos abrir la consola y ejecutaremos el siguiente comando npm start para poder ver los cambios que realizaremos a lo largo de este post.

Tabla de Contenido

  1. Creación del componente Main.js
  2. Integración de la API
  3. Obtener información de la película
  4. Creación y Configuración del modal para mostrar los detalles
  5. Paginación
  6. Conclusión

Empecemos!

  1. ## Creación del componente Main.js

Para empezar lo primero que haremos será eliminar los archivos que no usaremos, dejando nuestro proyecto como se muestra mas arriba en la estructura del proyecto.

Abriremos nuestro archivo App.js ubicado dentro de src, vamos a eliminar el import del logo, y modificaremos nuestro archivo dejándolo de la siguiente manera por los momentos.

import './App.css';

function App() {
  return (
    <div className="App">
      REACT OMDB
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Posterior a esto iremos a nuestra carpeta components dentro de la carpeta src (la crearemos en caso de no haberla creado aun), dentro de components crearemos un archivo llamado Main.js .

Abriremos nuestro Main.js, empezaremos importando los hooks useState y useEffect ya que los usaremos mas adelante, y también importaremos axios.

Crearemos una constante con el nombre de api donde colocaremos la ruta de la api, en este caso 'https://www.omdbapi.com/?' y también una constante para apiKey a la que le asignaremos nuestra key.

De momento solo retornaremos un div con el nombre de nuestro componente.

import React, {useState, useEffect} from 'react'
import axios from 'axios'

//api

const api = 'https://www.omdbapi.com/?'

//api key
const apiKey = 'apikey=18eaeb4f'

const Main = () => {

  return(
    <div>
      Main
    </div>
  )
}

export default Main
Enter fullscreen mode Exit fullscreen mode

Volveremos a nuestro App.js y importaremos nuestro componente Main.js como se muestra en el código de abajo, veremos que ya nos muestra el componente Main.js.

import React from 'react';
import './App.css'
//components
import Main from './components/Main'

function App() {
  return (
    <div className="App">
      REACT OMDB
      <Main />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Hello World

  1. ## Integración de la API

Ahora volveremos a nuestro componente Main.js y haremos un formulario para poder realizar una búsqueda con el nombre de la película, y hacer uso del hook useState, al hacer clic al botón de buscar se ejecutará la función que realizará la petición GET a la api, y de momento obtendremos la respuesta por consola.

import React, { useState, useEffect } from "react";
import axios from "axios";

//api

const api = "https://www.omdbapi.com/?";

//api key
const apiKey = "apikey=18eaeb4f";

const Main = () => {
  const [name, setName] = useState("");

  //get response from API
  const getInfo = () => {
    axios
      .get(api + apiKey + `&s=${name}` + "&type=movie" + "&page=1")
      .then((res) => {
        if (res) {
          console.log(res.data);
        }
      });
  };

  //submit the title entered
  const handleSubmit = (e) => {
    e.preventDefault();
    getInfo();
  };

  return (
    <div>
      <form>
        <div className='searchBar'>
          <label htmlFor='name'></label>
          <input
            type='text'
            name='name'
            placeholder='movie name'
            onChange={(e) => setName(e.target.value)}
          />
          <button type='submit' onClick={(e) => handleSubmit(e)}>
            Search
          </button>
        </div>
      </form>
    </div>
  );
};

export default Main;
Enter fullscreen mode Exit fullscreen mode

api response

Estamos recibiendo un objeto, con el número total de resultados (que usaremos mas adelante para crear la funcionalidad de paginación), y un arreglo con los 10 primeros títulos que encontró, con detalles como el poster, la fecha de estreno, el imdbID (que también usaremos mas adelante), y muchos más.

Usaremos nuevamente nuestro useState, en este caso con un arreglo de películas con el estado inicial vacío, y cambiará cuando obtengamos los resultados. Y ahora en el return devolveremos la lista de resultados si el arreglo tiene elementos, en caso contrario devolveremos null.

Haremos que nos devuelva por cada título, un poster, el título, y un botón details, que de momento no hace nada, y colocaremos como key el imdbId de cada título.

import React, { useState, useEffect } from "react";
import axios from "axios";

//api

const api = "https://www.omdbapi.com/?";

//api key
const apiKey = "apikey=18eaeb4f";

const Main = () => {
  const [name, setName] = useState("");
  const [movies, setMovies] = useState([])

  //get response from API
  const getInfo = () => {
    axios
      .get(api + apiKey + `&s=${name}` + "&type=movie" + "&page=1")
      .then((res) => {
        if (res) {
          setMovies(res.data.Search)
        }
      });
  };

  //submit the title entered
  const handleSubmit = (e) => {
    e.preventDefault();
    getInfo();
  };

  return (
    <div>
      <form>
        <div className='searchBar'>
          <label htmlFor='name'></label>
          <input
            type='text'
            name='name'
            placeholder='movie name'
            onChange={(e) => setName(e.target.value)}
          />
          <button type='submit' onClick={(e) => handleSubmit(e)}>
            Search
          </button>
        </div>
      </form>

      {movies ? 
      <div className="movies">
        {movies.map(movie => (
          <div key={movie.imdbID} className="movie">
            <img src={movie.Poster} alt=""/>
            <div className="movie-title">
              <p>{movie.Title}</p>
            </div>
            <button className="movie-detailsBtn" >Details</button>

          </div>))}
      </div> 
      : null}
    </div>
  );
};

export default Main;
Enter fullscreen mode Exit fullscreen mode

movies displayed

  1. ## Obtener información de la película

Ahora para el botón de detalles crearemos una función llamada getDetails, la cual se la pasará como argumento el id (imdbID) del título y se hará otra petición GET a la api con el id para que nos devuelva específicamente los datos de esa película, de momento los mostraremos por consola.

import React, { useState, useEffect } from "react";
import axios from "axios";

//api
const api = "https://www.omdbapi.com/?";

//api key
const apiKey = "apikey=18eaeb4f";

const Main = () => {
  const [name, setName] = useState("");
  const [movies, setMovies] = useState([])

  //get response from API
  const getInfo = () => {
    axios
      .get(api + apiKey + `&s=${name}` + "&type=movie" + "&page=1")
      .then((res) => {
        if (res) {
          setMovies(res.data.Search)
        }
      });
  };



  //submit the title entered
  const handleSubmit = (e) => {
    e.preventDefault();
    getInfo();
  };

  return (
    <div>
      <form>
        <div className='searchBar'>
          <label htmlFor='name'></label>
          <input
            type='text'
            name='name'
            placeholder='movie name'
            onChange={(e) => setName(e.target.value)}
          />
          <button type='submit' onClick={(e) => handleSubmit(e)}>
            Search
          </button>
        </div>
      </form>

      {movies ? 
      <div className="movies">
        {movies.map(movie => (
          <div key={movie.imdbID} className="movie">
            <img src={movie.Poster} alt=""/>
            <div className="movie-title">
              <p>{movie.Title}</p>
            </div>
            <button className="movie-detailsBtn" >Details</button>

          </div>))}
      </div> 
      : null}
    </div>
  );
};

export default Main;
Enter fullscreen mode Exit fullscreen mode

movie details from api

Vamos a añadir un estado de movieDetails que este inicializado como un objeto vacío, ahora en lugar de mostrar los detalles por consola vamos a actualizar el estado de movieDetails con esos datos.

import React, { useState, useEffect } from "react";
import axios from "axios";

//api

const api = "https://www.omdbapi.com/?";

//api key
const apiKey = "apikey=18eaeb4f";

const Main = () => {
  const [name, setName] = useState("");
  const [movies, setMovies] = useState([])
  const [movieDetails, setMovieDetails] = useState({})

  //get response from API
  const getInfo = () => {
    axios
      .get(api + apiKey + `&s=${name}` + "&type=movie" + "&page=1")
      .then((res) => {
        if (res) {
          setMovies(res.data.Search)
        }
      });
  };

  //get details
  const getDetails = (e, id) => {
    e.preventDefault()

    axios.get(api + apiKey + `&i=${id}`).then((res) => {
      if (res) {
        setMovieDetails(res.data)
      }
    })
  }

  //submit the title entered
  const handleSubmit = (e) => {
    e.preventDefault();
    getInfo();
  };

  return (
    <div>
      <form>
        <div className='searchBar'>
          <label htmlFor='name'></label>
          <input
            type='text'
            name='name'
            placeholder='movie name'
            onChange={(e) => setName(e.target.value)}
          />
          <button type='submit' onClick={(e) => handleSubmit(e)}>
            Search
          </button>
        </div>
      </form>

      {movies ? 
      <div className="movies">
        {movies.map(movie => (
          <div key={movie.imdbID} className="movie">
            <img src={movie.Poster} alt=""/>
            <div className="movie-title">
              <p>{movie.Title}</p>
            </div>
            <button className="movie-detailsBtn" 
            onClick={e => getDetails(e, movie.imdbID)}
            >Details</button>

          </div>))}
      </div> 
      : null}
    </div>
  );
};

export default Main;
Enter fullscreen mode Exit fullscreen mode
  1. ## Creación y Configuración del modal para mostrar los detalles

Para mostrar estos datos usaremos un modal que se muestre cada vez que hagamos clic en el botón "details", para esto iremos a nuestra carpeta components y crearemos un archivo llamado MovieModal.js, el cual de momento nos va a retornar esta estructura, (recuerda que las clases corresponden al css que cree).

const MovieModal = () => {
  return(
    <div className="modal display-block">
      <section className="modal-main">
        <div className="modal-body">

        </div>
        <button className="modal-closebtn" >Close</button>
      </section>
    </div>
  )
}

export default MovieModal
Enter fullscreen mode Exit fullscreen mode

Ahora para poder abrir este modal debemos volver a nuestro archivo Main.js:

1- Empezamos importando nuestro nuevo componente.

2- Declaramos un estado para el id seleccionado $const [selectedId, setSelectedId] = useState(null) .

3- Vamos a crear un estado para mostrar nuestro modal con $const [show, setShow] = useState(false) que será un booolean y estará inicializado en false.

4- Configuraremos la funcionalidad del modal con 3 funciones.

5- En nuestra función getDetails actualizaremos selectId con el id que se paso como argumento a la función, luego al recibir la respuesta ejecutaremos showModal() para mostrarlo.

6- Por ultimo en return debajo del botón colocaremos una condicional, si MovieDetails no esta vacío, si el selectedId es estrictamente igual al imdbdID de la película y si show esta en true, entonces nos va a retornar el componente de nuestro modal, de lo contrario no lo mostrará.

import React, { useState, useEffect } from "react";
import axios from "axios";

//components
import MovieModal from "./MovieModal";

//api
const api = "https://www.omdbapi.com/?";

//api key
const apiKey = "apikey=18eaeb4f";

const Main = () => {
  const [name, setName] = useState("");
  const [movies, setMovies] = useState([])
  const [selectedId, setSelectedId] = useState(null)
  const [movieDetails, setMovieDetails] = useState({})

  //modal
  const [show, setShow] = useState(false)


  //modal config

  const showModal = () => {
    setShow(true)
  }

  const hideModal = () => {

    setShow(false)
    setMovieDetails()
  }

  const handleClose = () => {
    hideModal()
  }

  //get response from API
  const getInfo = () => {
    axios
      .get(api + apiKey + `&s=${name}` + "&type=movie" + "&page=1")
      .then((res) => {
        if (res) {
          setMovies(res.data.Search)
        }
      });
  };

  //get details
  const getDetails = (e, id) => {
    e.preventDefault()

    setSelectedId(id)
    axios.get(api + apiKey + `&i=${id}`).then((res) => {
      if (res) {
        setMovieDetails(res.data)
        showModal()
      }
    })
  }

  //submit the title entered
  const handleSubmit = (e) => {
    e.preventDefault();
    getInfo();
  };

  return (
    <div>
      <form>
        <div className='searchBar'>
          <label htmlFor='name'></label>
          <input
            type='text'
            name='name'
            placeholder='movie name'
            onChange={(e) => setName(e.target.value)}
          />
          <button type='submit' onClick={(e) => handleSubmit(e)}>
            Search
          </button>
        </div>
      </form>

      {movies ? 
      <div className="movies">
        {movies.map(movie => (
          <div key={movie.imdbID} className="movie">
            <img src={movie.Poster} alt=""/>
            <div className="movie-title">
              <p>{movie.Title}</p>
            </div>
            <button className="movie-detailsBtn" 
            onClick={e => getDetails(e, movie.imdbID)}
            >Details</button>

            {/* modal */}
            {movieDetails && (selectedId===movie.imdbID) && show ? 
              <MovieModal/> : 
              <div className="modal display-none"></div>
            }

          </div>))}
      </div> 
      : null}
    </div>
  );
};

export default Main;
Enter fullscreen mode Exit fullscreen mode

Modal is working

Como podrás haber notado, no muestra la información y tampoco se puede cerrar, volvemos a Main.js y en la parte donde retornamos el modal vamos a pasar $handleClose, y los detalles con una propiedad que llamaremos movieInfo.

{/* modal */}
{movieDetails && (selectedId===movie.imdbID) && show ? 
  <MovieModal 
  movieInfo={movieDetails} 
  handleClose={handleClose}/> : 
  <div className="modal display-none"></div>
}
Enter fullscreen mode Exit fullscreen mode

Volvemos a nuestro MovieModal.js, pasaremos los props de la siguiente manera.

const MovieModal = ({movieInfo, handleClose}) => {
  return(
    .
    .
    .
  )
}
export default MovieModal
Enter fullscreen mode Exit fullscreen mode

Ahora modificamos el return para que devuelva algunos datos, (puedes pasar mas si lo deseas), y al botón de close haremos que ejecute la función handleClose cuando se le haga clic.

const MovieModal = ({ movieInfo, handleClose }) => {
  return (
    <div className='modal display-block'>
      <section className='modal-main'>
        <div className='modal-body'>
          <div className='modal-img'>
            <img src={movieInfo.Poster} alt='Poster' />
          </div>
        </div>
        <div className='modal-info'>
          <p>
            <b>Actors:</b> {movieInfo.Actors}
          </p>
          <p>
            <b>Genre:</b> {movieInfo.Genre}
          </p>
          <p>
            <b>Director:</b> {movieInfo.Director}
          </p>
          <p>
            <b>Released:</b> {movieInfo.Released}
          </p>
          <p>
            <b>Plot:</b> {movieInfo.Plot}
          </p>
        </div>
        <button className='modal-closebtn' onClick={handleClose}>
          Close
        </button>
      </section>
    </div>
  );
};

export default MovieModal;
Enter fullscreen mode Exit fullscreen mode

modal with details

  1. ## Paginación

Ahora que tenemos esa sección lista, crearemos la funcionalidad de paginación y asi poder ver mas resultados.

Vovlemos a nuestro componente Main.js, al realizar la peticion GET a la api nos devuelven un objeto con una propiedad llamada totalResults, esta propiedad será clave para crear la funcionalidad de paginación.

total results

Lo primero que haremos será añadir un nuevo estado, luego iremos a nuestra función getInfo y la modificaremos para que actualice totalResults con los datos correspondientes

const Main = () => {
  const [name, setName] = useState("");
  const [movies, setMovies] = useState([])
  const [selectedId, setSelectedId] = useState(null)
  const [movieDetails, setMovieDetails] = useState({})

  //modal
  const [show, setShow] = useState(false)

  //pagination
  const [totalResults, setTotalResults] = useState()
  .
  .
  .

  //get response from API
  const getInfo = () => {
    axios
      .get(api + apiKey + `&s=${name}` + "&type=movie" + "&page=1")
      .then((res) => {
        if (res) {
          setMovies(res.data.Search)
          setTotalResults(res.data.totalResults)
        }
      });
  };

  .
  .
  .
Enter fullscreen mode Exit fullscreen mode

Con ayuda de totalResults podremos calcular el número de páginas que tendrá la busqueda que realicemos, crearemos otro estado const [numberOfPages, setNumberOfPages] = useState() y construiremos una función getNumberOfPages para obtener el número de páginas de nuestra busqueda.

En la función divideremos entre 10 porque solo obtenemos 10 resultados como máximo por página, por lo que usaremos el operador módulo para ver si la división arroja residuo, en caso de que arroje residuo, argegaremos una página adicional. usaremos parseInt() ya que totalResults es un string. Finalmente actualizaremos numberOfPages con el valor del número de páginas.

.
.
.
//pagination
  const [totalResults, setTotalResults] = useState()
  const [numberOfPages, setNumberOfPages] = useState()
.
.
.

const getNumberOfPages = () => {
  if (totalResults % 10 > 0) {
    const numberOfpages = parseInt((totalResults / 10) + 1)
    setNumberOfPages(numberOfpages)
    return
  }
    const numberOfpages = parseInt(totalResults / 10)
    setNumberOfPages(numberOfpages)
}
Enter fullscreen mode Exit fullscreen mode

Ahora crearemos un estado que se va a encargar de actualizarce con la página actual, que será la página que seleccionemos const [currentPage, setCurrentPage] = useState()

Modificaremos la función getInfo() de la siguiente manera para que cuando hagamos nuestra primera busqueda, actualice currentPage en 1, y empezaremos a mostrar los números de las páginas con la siguiente lógica después del return.

Si ya tenemos el número de páginas, entonces mostramos un div con las páginas, de lo contrario no lo renderizaremos. Como mostraremos las páginas enumeradas haremos lo siguiente, si la página anterior currentPage -1 es igual a 0, no la mostrarémos, de lo contrario mostraremos currentPage - 1, luego la página actual, es decir currentPage, y por ultimo la página siguiente con currentPage + 1 .

.
.
.
//pagination
const [totalResults, setTotalResults] = useState()
const [numberOfPages, setNumberOfPages] = useState()
const [currentPage, setCurrentPage] = useState()
.
.
.

//get response from API
const getInfo = () => {
  axios
    .get(api + apiKey + `&s=${name}` + "&type=movie" + "&page=1")
    .then((res) => {
      if (res) {
        setMovies(res.data.Search);
        setTotalResults(res.data.totalResults);
        setCurrentPage(1)
      }
    });
};


return(
  {numberOfPages ? (
    <div className='pages'>
      {/* if prev page is 0 it wont show */}
      {currentPage - 1 === 0 ? null : (
        <b >{currentPage - 1}</b>
      )}
      <b  className='actualPage'>
        {currentPage}
      </b>
      <b >{currentPage + 1}</b>
    </div>
  ) : null}
)
Enter fullscreen mode Exit fullscreen mode

pagination

De momento solo podemos ver números, pero no tiene ninguna funcionalidad, hagámosla.

1- usaremos useEffect() para que ejecute getNumbersOfPages() .

2- Modificaremos nuestra función getInfo() y le pasaremos como argumento pageNumber, de tal manera de que si le pasamos pageNumber hará la petición GET a la api con el valor de pageNumber en el parametro de page, caso contrario nos devolvera el valor con el valor de la página en 1 como veniamos haciendo hasta ahora.

3- Crearemos un arreglo de páginas, el cual llenaremos con ayuda de un ciclo for que empezaremos en 1 e iterará el numero de veces correspondiente a numberOfPages, ejemplo (si el numero de páginas es 5, pasara 5 veces, y tendremos nuestro arreglo pages con 5 valores).

4- Crearemos una función goTo(pageNumber) que tendrá como argumento pageNumber, cada vez que se ejecute esta función actualizaremos currentPage con el valor de la página seleccionada, es decir pageNumber. Y luego se ejecutará getInfo con esa misma página que seleccionamos.

5- En la parte donde renderizamos nuestra paginación, haremos unas modificaciones pata que al hacer clic en el número de la página, ejecute la funcion goTo con la página que seleccionamos.

.
.
.

//get response from API
const getInfo = (pageNumber) => {
  if (pageNumber) {
    axios
      .get(
        api + apiKey + `&s=${name}` + "&type=movie" + `&page=${pageNumber}`
      )
      .then((res) => {
        if (res) {
          setMovies(res.data.Search);
          setTotalResults(res.data.totalResults);
        }
      });
    return;
  }
  axios
    .get(api + apiKey + `&s=${name}` + "&type=movie" + "&page=1")
    .then((res) => {
      if (res) {
        setMovies(res.data.Search);
        setTotalResults(res.data.totalResults);
        setCurrentPage(1);
      }
    });
};

//getnumberOFpageseffect
useEffect(() => {
  getNumberOfPages();
});

const pages = [];

for (let i = 1; i <= numberOfPages; i++) {
  pages.push(<p key={i} onClick={e => goTo(i)}>{i}</p>)
}

const goTo = (pageNumber) => {

  setCurrentPage(pageNumber)
  getInfo(pageNumber)
  window.scrollTo(0, 0)
}


return(
  .
  .
  .
  {numberOfPages ? (
    <div className='pages'>
      {/* if prev page is 0 it wont show */}
      {currentPage - 1 === 0 ? null : <b onClick={e => goTo(currentPage-1)}>{currentPage - 1}</b>}
      <b onClick={e => goTo(currentPage)}className='actualPage'>{currentPage}</b>
      <b onClick={e => goTo(currentPage+1)}>{currentPage + 1}</b>
    </div>
  ) : null}
)
Enter fullscreen mode Exit fullscreen mode

Finalmente, nuestro archivo debe verse así.

import React, { useState, useEffect } from "react";
import axios from "axios";

//components
import MovieModal from "./MovieModal";

//api
const api = "https://www.omdbapi.com/?";

//api key
const apiKey = "apikey=18eaeb4f";

const Main = () => {
  const [name, setName] = useState("");
  const [movies, setMovies] = useState([]);
  const [selectedId, setSelectedId] = useState(null);
  const [movieDetails, setMovieDetails] = useState({});

  //modal
  const [show, setShow] = useState(false);

  //pagination
  const [totalResults, setTotalResults] = useState(0);
  const [numberOfPages, setNumberOfPages] = useState();
  const [currentPage, setCurrentPage] = useState();

  const getNumberOfPages = () => {
    if (totalResults % 10 > 0) {
      const numberOfpages = parseInt(totalResults / 10 + 1);
      setNumberOfPages(numberOfpages);
      return;
    }
    const numberOfpages = parseInt(totalResults / 10);
    setNumberOfPages(numberOfpages);
  };

  //modal config
  const showModal = () => {
    setShow(true);
  };

  const hideModal = () => {
    setShow(false);
    setMovieDetails();
  };

  const handleClose = () => {
    hideModal();
  };

  //get response from API
  const getInfo = (pageNumber) => {
    if (pageNumber) {
      axios
        .get(
          api + apiKey + `&s=${name}` + "&type=movie" + `&page=${pageNumber}`
        )
        .then((res) => {
          if (res) {
            setMovies(res.data.Search);
            setTotalResults(res.data.totalResults);
          }
        });
      return;
    }
    axios
      .get(api + apiKey + `&s=${name}` + "&type=movie" + "&page=1")
      .then((res) => {
        if (res) {
          setMovies(res.data.Search);
          setTotalResults(res.data.totalResults);
          setCurrentPage(1);
        }
      });
  };

  //get details
  const getDetails = (e, id) => {
    e.preventDefault();

    setSelectedId(id);
    axios.get(api + apiKey + `&i=${id}`).then((res) => {
      if (res) {
        setMovieDetails(res.data);
        showModal();
      }
    });
  };

  //submit the title entered
  const handleSubmit = (e) => {
    e.preventDefault();
    getInfo();
  };

  //getnumberOFpageseffect
  useEffect(() => {
    getNumberOfPages();
  });

  const pages = [];

  for (let i = 1; i <= numberOfPages; i++) {
    pages.push(
      <p key={i} onClick={(e) => goTo(i)}>
        {i}
      </p>
    );
  }

  const goTo = (pageNumber) => {
    setCurrentPage(pageNumber);
    getInfo(pageNumber);
    window.scrollTo(0, 0);
  };

  return (
    <div>
      <form>
        <div className='searchBar'>
          <label htmlFor='name'></label>
          <input
            type='text'
            name='name'
            placeholder='movie name'
            onChange={(e) => setName(e.target.value)}
          />
          <button type='submit' onClick={(e) => handleSubmit(e)}>
            Search
          </button>
        </div>
      </form>

      {movies ? (
        <div className='movies'>
          {movies.map((movie) => (
            <div key={movie.imdbID} className='movie'>
              <img src={movie.Poster} alt='' />
              <div className='movie-title'>
                <p>{movie.Title}</p>
              </div>
              <button
                className='movie-detailsBtn'
                onClick={(e) => getDetails(e, movie.imdbID)}
              >
                Details
              </button>

              {/* modal */}
              {movieDetails && selectedId === movie.imdbID && show ? (
                <MovieModal
                  movieInfo={movieDetails}
                  handleClose={handleClose}
                />
              ) : (
                <div className='modal display-none'></div>
              )}
            </div>
          ))}
        </div>
      ) : null}

      {numberOfPages ? (
        <div className='pages'>
          {/* if prev page is 0 it wont show */}
          {currentPage - 1 === 0 ? null : (
            <b onClick={(e) => goTo(currentPage - 1)}>{currentPage - 1}</b>
          )}
          <b onClick={(e) => goTo(currentPage)} className='actualPage'>
            {currentPage}
          </b>
          <b onClick={(e) => goTo(currentPage + 1)}>{currentPage + 1}</b>
        </div>
      ) : null}
    </div>
  );
};

export default Main;
Enter fullscreen mode Exit fullscreen mode
  1. ## Conclusión

En este post aprendimos a integrar una api a una aplicación de react de forma básica.

Realmente espero que hayas podido seguir el post sin problemas, y en caso de que no lo hayas podido hacer te pido disculpas, y que por favor me dejes tus dudas o comentarios.

Como mencioné anteriormente, la interfaz que creé para este ejemplo es muy sencilla, se puede mejorar asi como el código, te animo a que lo mejores y le agregues mas funcionalidades.

Puedes contactarme por telegram si necesitas contratar a un desarrollador Full Stack.

También puedes contactarme por discord Appu#9136

Puedes encontrar el repo aquí en caso de que lo desees clonar.

Gracias por tu tiempo.

Top comments (0)