suchen
HeimWeb-FrontendCSS-TutorialErstellen einer Movie Finder-Website mit React

Building a Movie Finder Website using React

Einführung

In diesem Blog werden wir durch den Prozess der Erstellung einer Movie Finder-Website mit React und der OMDB-API gehen. Auf der Website können Benutzer Filme nach Kategorien wie „Avengers“, „Star Wars“ und „Serien“ durchsuchen und mithilfe spezifischer Suchanfragen nach Filmen suchen. Jeder Film verfügt über eine Detailseite, sodass Sie ganz einfach mehr über Ihre Lieblingsfilme erfahren können.

Projektübersicht

Movie Finder-Website ermöglicht Benutzern Folgendes:

  • Durchsuchen Sie Kategorien wie Avengers und Star Wars.
  • Suchen Sie nach Filmen anhand von Schlüsselwörtern.
  • Detaillierte Filminformationen anzeigen (Poster, Genre, Regisseur, Schauspieler und mehr).
  • Navigieren Sie einfach durch die Website mit einem klaren, modernen Design.

Merkmale

  • Daten dynamisch mithilfe der OMDB-API abrufen.
  • Responsives Design für ein besseres Benutzererlebnis.
  • Suchfunktion, die sofortige Ergebnisse liefert.
  • Anzeigen werden geladen, während Daten abgerufen werden.
  • Details zu einzelnen Filmen finden Sie auf einer separaten Seite.

Verwendete Technologien

  • React: Frontend-Bibliothek zum Erstellen von UI-Komponenten.
  • React Router: Für Navigation und Routing.
  • Axios: Zum Senden von HTTP-Anfragen an die OMDB-API.
  • OMDB-API: Zum Abrufen von Filmdetails.
  • CSS: Zum Gestalten der Anwendung.

Projektstruktur

Hier ist die Verzeichnisstruktur für das Projekt:

movie-finder/
├── public/
├── src/
│   ├── components/
│   │   └── Navbar.js
│   │   └── Footer.js
│   ├── pages/
│   │   └── Home.js
│   │   └── Movies.js
│   │   └── Series.js
│   │   └── SearchResults.js
│   │   └── MovieDetail.js
│   └── App.js
│   └── App.css
└── package.json

Installation

  1. Klonen Sie das Repository:

    git clone https://github.com/abhishekgurjar-in/movie-finder.git
    cd movie-finder
    
  2. Abhängigkeiten installieren:

    npm install
    
  3. Holen Sie sich Ihren API-Schlüssel von der OMDB-API.

  4. Erstellen Sie eine .env-Datei im Projektstamm und fügen Sie Ihren API-Schlüssel hinzu:

    REACT_APP_OMDB_API_KEY=yourapikey
    
  5. Führen Sie das Projekt aus:

    npm start
    

Verwendung

1. Startseite

Die Startseite zeigt zwei Kategorien von Filmen: Avengers und Star Wars. Wenn der Benutzer auf eine Filmkarte klickt, wird er zur detaillierten Filmseite weitergeleitet.

Code-Snippet von Home.js:

import React, { useEffect, useState } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import Movies from "./Movies";
import Series from "./Series";

const Home = () => {
  const [avengersMovies, setAvengersMovies] = useState([]);
  const [starWarsMovies, setStarWarsMovies] = useState([]);
  const [loadingAvengers, setLoadingAvengers] = useState(true);
  const [loadingStarWars, setLoadingStarWars] = useState(true);
  const navigate = useNavigate();

  useEffect(() => {
    fetchMovies("Avengers", setAvengersMovies, setLoadingAvengers);
    fetchMovies("Star Wars", setStarWarsMovies, setLoadingStarWars);
  }, []);

  const fetchMovies = (query, setMovies, setLoading) => {
    axios
      .get(`http://www.omdbapi.com/?s=${query}&apikey=you_api_key`)
      .then((response) => {
        if (response.data.Search) {
          setMovies(response.data.Search);
        } else {
          setMovies([]); // Clear movies if no results
        }
      })
      .catch((error) => {
        console.error(`There was an error fetching the ${query} movies!`, error);
        setMovies([]); // Clear movies if there is an error
      })
      .finally(() => {
        setLoading(false);
      });
  };

  const handleCardClick = (id) => {
    navigate(`/movie/${id}`);
  };

  const renderMovies = (movies, loading) => (
    loading ? (
      <div classname="loader"><div classname="load"></div></div>
    ) : (
      <div classname="cards">
        {movies.length > 0 ? (
          movies.map((movie) => (
            <div key="{movie.imdbID}" classname="card" onclick="{()"> handleCardClick(movie.imdbID)}>
              <img src="%7Bmovie.Poster%7D" alt="{movie.Title}">
              <h2 id="movie-Title">{movie.Title}</h2>
            </div>
          ))
        ) : (
          <p>No movies found.</p>
        )}
      </div>
    )
  );

  return (
    
      <div classname="home">
        <div classname="movie-category">
          <h4 id="Avengers-Movies">Avengers Movies</h4>
          {renderMovies(avengersMovies, loadingAvengers)}
        </div>
        <br>
        <br>
        <div classname="movie-category">
          <h4 id="Star-Wars-Movies">Star Wars Movies</h4>
          {renderMovies(starWarsMovies, loadingStarWars)}
        </div>
      </div>
      <movies></movies>
      <series></series>
    >
  );
};

export default Home;

2. Suchfunktion

Der Benutzer kann über die Suchleiste oben auf der Website nach jedem Film suchen. Suchergebnisse werden basierend auf der Anfrage des Benutzers von der OMDB-API abgerufen.

Code-Snippet von SearchResults.js:

import React, { useEffect, useState } from "react";
import axios from "axios";
import { useParams, useNavigate } from "react-router-dom";

const SearchResults = () => {
  const [movies, setMovies] = useState([]);
  const [loading, setLoading] = useState(false);
  const { query } = useParams();
  const navigate = useNavigate(); // Add this line to use navigate

  useEffect(() => {
    if (query) {
      setLoading(true);  // Set loading to true before starting the fetch
      axios
        .get(`http://www.omdbapi.com/?s=${query}&apikey=your_api_key`)
        .then((response) => {
          if (response.data.Search) {
            setMovies(response.data.Search);
          } else {
            setMovies([]); // Clear movies if no results
          }
        })
        .catch((error) => {
          console.error("There was an error fetching the movie data!", error);
        })
        .finally(() => {
          setLoading(false);  // Set loading to false once fetch is complete
        });
    }
  }, [query]);

  const handleCardClick = (id) => {
    navigate(`/movie/${id}`); // Navigate to movie detail page
  };

  return (
    <div classname="search-results">
      <h4 id="Search-Results-for-query">Search Results for "{query}"</h4>
      {loading ? (
        <div classname="loader"><div classname="load"></div></div>  // Loader
      ) : (
        <div classname="cards">
          {movies.length > 0 ? (
            movies.map((movie) => (
              <div key="{movie.imdbID}" classname="card" onclick="{()"> handleCardClick(movie.imdbID)}>
                <img src="%7Bmovie.Poster%7D" alt="{movie.Title}">
                <h2 id="movie-Title">{movie.Title}</h2>
              </div>
            ))
          ) : (
            <p>No results found.</p>
          )}
        </div>
      )}
    </div>
  );
};

export default SearchResults;

3. Filmdetailseite

Wenn ein Benutzer auf einen Film klickt, wird er zur Filmdetailseite weitergeleitet. Auf dieser Seite werden der Titel, das Poster, die Handlung, die Schauspieler und mehr des Films angezeigt.

Codeausschnitt aus MovieDetail.js:

import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { useParams } from 'react-router-dom';

const MovieDetail = () => {
  const [movie, setMovie] = useState(null);
  const [loading, setLoading] = useState(true);
  const { id } = useParams();

  useEffect(() => {
    axios.get(`http://www.omdbapi.com/?i=${id}&apikey=your_api_key`)
      .then((response) => {
        setMovie(response.data);
      })
      .catch((error) => {
        console.error("There was an error fetching the movie details!", error);
      })
      .finally(() => {
        setLoading(false);
      });
  }, [id]);

  if (loading) return <div classname="loader">
    <div classname="load"></div>
  </div>;
  if (!movie) return <div classname="loader">No movie data found!</div>;

  return (
    <div classname="movie-detail">

<div classname="detail-box">
<h1 id="movie-Title">{movie.Title}</h1>
<p><strong>Year:</strong> {movie.Year}</p>
      <p><strong>Rating:</strong> {movie.imdbRating}</p>
      <p><strong>Genre:</strong> {movie.Genre}</p>
      <p><strong>Director:</strong> {movie.Director}</p>
      <p><strong>Actors:</strong> {movie.Actors}</p>
      <p><strong>Plot:</strong> {movie.Plot}</p>
      <p><strong>Runtime:</strong> {movie.Runtime}</p>
      <p><strong>Language:</strong> {movie.Language}</p>
      <p><strong>Country:</strong> {movie.Country}</p>
      <p><strong>Awards:</strong> {movie.Awards}</p>
</div>
    <div classname="img-box">
    <img src="%7Bmovie.Poster%7D" alt="{movie.Title}">
    </div>
    </div>
  );
};

export default MovieDetail;

4. Film- und Serienseiten

Auf den Seiten

Movies.js und Series.js werden jeweils Filme und Fernsehserien aufgeführt.

Codeausschnitt aus Movies.js:

import React, { useEffect, useState } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";

const Movies = () => {
  const [movies, setMovies] = useState([]);
  const navigate = useNavigate();

  useEffect(() => {
    axios
      .get(`http://www.omdbapi.com/?s=Avengers&type=movie&apikey=${process.env.REACT_APP_OMDB_API_KEY}`)
      .then(response => setMovies(response.data.Search || []))
      .catch(error => console.error(error));
  }, []);

  const handleCardClick = (id) => {
    navigate(`/detail/${id}`);
  };

  return (
    <div classname="movies">
      <h2 id="Movies">Movies</h2>
      <div classname="cards">
        {movies.map(movie => (
          <div key="{movie.imdbID}" classname="card" onclick="{()"> handleCardClick(movie.imdbID)}>
            <img src="%7Bmovie.Poster%7D" alt="{movie.Title}">
            <h3 id="movie-Title">{movie.Title}</h3>
          </div>
        ))}
      </div>
    </div>
  );
};

export default Movies;

Codeausschnitt aus Series.js:

import React, { useEffect, useState } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";

const Series = () => {
  const [series, setSeries] = useState([]);
  const navigate = useNavigate();

  useEffect(() => {
    axios
      .get(`http://www.omdbapi.com/?s=Star Wars&type=series&apikey=${process.env.REACT_APP_OMDB_API_KEY}`)
      .then(response => setSeries(response.data.Search || []))
      .catch(error => console.error(error));
  }, []);

  const handleCardClick = (id) => {
    navigate(`/detail/${id}`);
  };

  return (
    <div classname="series">
      <h2 id="TV-Series">TV Series</h2>
      <div classname="cards">
        {series.map(show => (
          <div key="{show.imdbID}" classname="card" onclick="{()"> handleCardClick(show.imdbID)}>
            <img src="%7Bshow.Poster%7D" alt="{show.Title}">
            <h3 id="show-Title">{show.Title}</h3>
          </div>
        ))}
      </div>
    </div>
  );
};

export default Series;

5. Navbar-Komponente

Mit der Navbar-Komponente können Benutzer zwischen verschiedenen Seiten navigieren und eine Suche durchführen.

Navbar.js aktualisiert

import React, { useState } from "react";
import { NavLink, Link } from "react-router-dom";

const Navbar = () => {
  const [searchQuery, setSearchQuery] = useState("");

  const handleSearch = (event) => {
    if (event.key === 'Enter' && searchQuery.trim()) {
      document.getElementById('search-link').click();
    }
  };

  return (
    <div classname="navbar">
      <div classname="logo">
        <h1 id="Movie-Finder">Movie Finder</h1>
      </div>

      <div classname="page-list">
        <navlink to="/">
          <h4 id="Home">Home</h4>
        </navlink>
        <navlink to="/movies">
          <h4 id="Movies">Movies</h4>
        </navlink>
        <navlink to="/series">
          <h4 id="TV-Series">TV Series</h4>
        </navlink>
      </div>
      <div classname="search-box">
        <input type="text" placeholder="Search for movies or series" value="{searchQuery}" onchange="{(e)"> setSearchQuery(e.target.value)}
          onKeyDown={handleSearch}
        />
        <link to="{`/search/${searchQuery}`}" id="search-link">
          <button>Search</button>
        
      </div>
    </div>
  );
};

export default Navbar;

6. Fußzeilenkomponente

Die Footer-Komponente stellt eine einfache Fußzeilennachricht bereit.

Footer.js

import React from 'react';

const Footer = () => {
  return (
    <div classname="footer">
      Made with <span>❤️</span> by Abhishek Gurjar
    </div>
  );
};

export default Footer;
*{
  box-sizing: border-box;
}
body{
  font-family: sans-serif;
  margin: 0;
  padding: 0;
}
.navbar {
  padding-inline: 100px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: red;
}
.search-btn{
  background-color: red;
}
.logo h1{
  font-size: 25px;
  color:black;
  }
.page-list {
  display: flex;
  align-items: center;
  gap: 40px;
}

.page-list a{
  color: white;
  text-decoration: none;
  font-size: 20px;
}
.page-list a:hover{
color: black;
}
.page-list a.active{
  color: black;
}
.search-box{
  box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
  background-color:white;
  color: gray;
  width: 250px;
  height: 40px;
  border-radius: 50px;
  overflow: hidden;
}
.search-box input{
  width: 200px;
  height: 40px;
  margin-left: 10px;
  border: none;
  outline: none;

}
.home{
  margin-block: 40px;
  margin-inline: 60px;

}
.home h4{
  font-size: 16px;
}


.movies{
  margin-block: 40px;
  margin-inline: 60px;

}
.movies h4{
  font-size: 16px;
}
.cards{
  display: flex;
flex-wrap: wrap;
  align-items:center ;
  justify-content: space-between;
  gap: 10px;
}
.card{
  width:200px;
  height:360px;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
}
.card img{
  width: 200px;
  height: 290px;
  object-fit: cover;
}
.card h2{
  margin: 10px;
  font-size: 16px;
text-align: center;
}

.series{
  margin-block: 40px;
  margin-inline: 60px;
}
.series h4{
  font-size: 16px;
}
.home{
  margin-block: 40px;
  margin-inline: 60px;

}
.search-results{
  margin-block: 40px;
  margin-inline: 60px;
}
.search-results h4{
  font-size: 16px;
}

.loader{
  min-height: 90vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* HTML: <div class="loader"></div> */
.load {
  width: 50px;
  padding: 8px;
  aspect-ratio: 1;
  border-radius: 50%;
  background: #ff1900;
  --_m: 
    conic-gradient(#0000 10%,#000),
    linear-gradient(#000 0 0) content-box;
  -webkit-mask: var(--_m);
          mask: var(--_m);
  -webkit-mask-composite: source-out;
          mask-composite: subtract;
  animation: l3 1s infinite linear;
}
@keyframes l3 {to{transform: rotate(1turn)}}


.movie-detail {
  margin-block: 40px;
  margin-inline: 60px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
}
img-box{
  width: 50%;
}
.movie-detail img {
  border-radius: 10px;
width: 330px;
 height: auto;
 object-fit: cover;
 box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
}

.detail-box{
  width: 50%;
}
.movie-detail p {
  font-size: 18px;
  margin: 10px 0;
}

.movie-detail a {
  display: inline-block;
  margin-top: 20px;
  color: #007bff;
  text-decoration: none;
}

.movie-detail a:hover {
  text-decoration: underline;
}


.footer{
  width: 100%;
  background-color: red;
  text-align: center;
  color: white;
  padding: 20px;
}

Live-Demo

Sie können sich hier die Live-Demo der Movie Finder-Website ansehen.

Abschluss

In diesem Blog haben wir gelernt, wie man mit React, React Router und Axios eine Movie Finder-Website erstellt. Dieses Projekt zeigt, wie man mit einer öffentlichen API interagiert, den Status in React verwaltet und ein einfaches, aber funktionales Erlebnis beim Durchsuchen von Filmen erstellt.

Fühlen Sie sich frei, das Design anzupassen und weitere Funktionen wie Benutzerrezensionen oder Filmbewertungen hinzuzufügen, um es dynamischer zu gestalten!


Credits

  • OMDB-API
  • Reagieren
  • React Router

Autor

Abhishek Gurjar ist ein engagierter Webentwickler, der sich mit der Entwicklung praktischer und funktionaler Webanwendungen beschäftigt. Schauen Sie sich weitere seiner Projekte auf GitHub an.

Das obige ist der detaillierte Inhalt vonErstellen einer Movie Finder-Website mit React. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
So viele FarblinksSo viele FarblinksApr 13, 2025 am 11:36 AM

Es gab in letzter Zeit eine Reihe von Werkzeugen, Artikeln und Ressourcen über Farbe. Bitte erlauben Sie mir, ein paar Registerkarten zu schließen, indem Sie sie hier für Ihren Vergnügen zusammenrunden.

Wie automatische Margen in Flexbox funktionierenWie automatische Margen in Flexbox funktionierenApr 13, 2025 am 11:35 AM

Robin hat dies schon einmal abgedeckt, aber ich habe in den letzten Wochen einige Verwirrung darüber gehört und gesehen, wie eine andere Person einen Stich gemacht hat, um es zu erklären, und ich wollte

Bewegliche Regenbogen unterstreichtBewegliche Regenbogen unterstreichtApr 13, 2025 am 11:27 AM

Ich liebe das Design der Sandwich -Site. Unter vielen schönen Merkmalen befinden sich diese Schlagzeilen mit Regenbogenuntergründen, die sich beim Scrollen bewegen. Es ist nicht

Neues Jahr, neuer Job? Lassen Sie einen netzbetriebenen Lebenslauf machen!Neues Jahr, neuer Job? Lassen Sie einen netzbetriebenen Lebenslauf machen!Apr 13, 2025 am 11:26 AM

Viele beliebte Lebenslaufdesigns machen den verfügbaren Seitenraum optimal, indem sie Abschnitte in Gitterform legen. Verwenden wir ein CSS -Netz, um ein Layout zu erstellen, das

Eine Möglichkeit, die Benutzer aus der Gewohnheit herauszubrechen, zu viel neu zu ladenEine Möglichkeit, die Benutzer aus der Gewohnheit herauszubrechen, zu viel neu zu ladenApr 13, 2025 am 11:25 AM

Seiten -Nachladen sind eine Sache. Manchmal aktualisieren wir eine Seite, wenn wir der Meinung sind, dass sie nicht mehr reagiert, oder glauben, dass neue Inhalte verfügbar sind. Manchmal sind wir nur sauer auf

Domänengetriebenes Design mit ReactDomänengetriebenes Design mit ReactApr 13, 2025 am 11:22 AM

Es gibt nur sehr wenige Anleitungen zur Organisation von Front-End-Anwendungen in der Welt der Reaktionen. (Bewegen Sie einfach Dateien um, bis es sich „richtig anfühlt“, lol). Die Wahrheit

Erkennen inaktiver BenutzerErkennen inaktiver BenutzerApr 13, 2025 am 11:08 AM

Meistens kümmert es Sie sich nicht wirklich darum, ob ein Benutzer aktiv mit Ihrer Anwendung inaktiv oder vorübergehend inaktiv ist. Inaktiv, was vielleicht sie vielleicht

Wufoo ZapierWufoo ZapierApr 13, 2025 am 11:02 AM

Wufoo war immer großartig bei Integrationen. Sie haben Integrationen mit bestimmten Apps wie Kampagnenmonitor, MailChimp und Typkit, aber auch sie

See all articles

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
4 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Dreamweaver Mac

Dreamweaver Mac

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

SublimeText3 Linux neue Version

SublimeText3 Linux neue Version

SublimeText3 Linux neueste Version

WebStorm-Mac-Version

WebStorm-Mac-Version

Nützliche JavaScript-Entwicklungstools

SecLists

SecLists

SecLists ist der ultimative Begleiter für Sicherheitstester. Dabei handelt es sich um eine Sammlung verschiedener Arten von Listen, die häufig bei Sicherheitsbewertungen verwendet werden, an einem Ort. SecLists trägt dazu bei, Sicherheitstests effizienter und produktiver zu gestalten, indem es bequem alle Listen bereitstellt, die ein Sicherheitstester benötigen könnte. Zu den Listentypen gehören Benutzernamen, Passwörter, URLs, Fuzzing-Payloads, Muster für vertrauliche Daten, Web-Shells und mehr. Der Tester kann dieses Repository einfach auf einen neuen Testcomputer übertragen und hat dann Zugriff auf alle Arten von Listen, die er benötigt.