導入
このブログでは、React と OMDB API を使用して Movie Finder Web サイトを構築するプロセスを順を追って説明します。この Web サイトでは、ユーザーはアベンジャーズ、スター ウォーズ、シリーズなどのカテゴリ別に映画を閲覧したり、特定のクエリを使用して映画を検索したりできます。各映画には詳細ページがあり、お気に入りの映画について簡単に詳しく調べることができます。
プロジェクト概要
Movie Finder Web サイト では、ユーザーは次のことが可能になります:
- アベンジャーズやスター ウォーズなどのカテゴリを参照します。
- キーワードで映画を検索します。
- 映画の詳細情報 (ポスター、ジャンル、監督、俳優など) を表示します。
- すっきりとしたモダンなデザインで、ウェブサイト内を簡単に移動できます。
特徴
- OMDB API を使用してデータを動的に取得します。
- ユーザーエクスペリエンスを向上させるレスポンシブデザイン。
- 即座に結果が得られる検索機能。
- データのフェッチ中にインジケーターを読み込みます。
- 個々の映画の詳細については、別のページをご覧ください。
使用されている技術
- React: UI コンポーネントを構築するためのフロントエンド ライブラリ。
- React Router: ナビゲーションとルーティング用。
- Axios: OMDB API への HTTP リクエストを作成します。
- OMDB API: 映画の詳細を取得します。
- CSS: アプリケーションのスタイルを設定します。
プロジェクトの構造
プロジェクトのディレクトリ構造は次のとおりです:
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
インストール
-
リポジトリのクローンを作成します:
git clone https://github.com/abhishekgurjar-in/movie-finder.git cd movie-finder
-
依存関係をインストールします:
npm install
OMDB API から API キーを取得します。
-
プロジェクト ルートに .env ファイルを作成し、API キーを追加します。
REACT_APP_OMDB_API_KEY=yourapikey
-
プロジェクトを実行します:
npm start
使用法
1. ホームページ
ホームページでは、アベンジャーズとスター・ウォーズという 2 つのカテゴリの映画が紹介されています。ユーザーがムービー カードをクリックすると、映画の詳細ページにリダイレクトされます。
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. 検索機能
ユーザーは、Web サイトの上部にある検索バーを使用して映画を検索できます。検索結果は、ユーザーのクエリに基づいて OMDB API から取得されます。
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. 動画詳細ページ
ユーザーが映画をクリックすると、映画の詳細ページにリダイレクトされます。このページには、映画のタイトル、ポスター、あらすじ、俳優などが表示されます。
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. 映画とシリーズのページ
Movies.js と Series.js ページには、それぞれ映画とテレビ シリーズがリストされています。
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;
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 コンポーネントを使用すると、ユーザーはさまざまなページ間を移動し、検索を実行できます。
Navbar.js を更新しました
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. フッターコンポーネント
フッター コンポーネントは、単純なフッター メッセージを提供します。
フッター.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; }
ライブデモ
ここで Movie Finder Web サイトのライブデモをチェックできます。
結論
このブログでは、React、React Router、Axios を使用して Movie Finder Web サイトを作成する方法を学びました。このプロジェクトでは、パブリック API と対話し、React で状態を管理し、シンプルでありながら機能的なムービー閲覧エクスペリエンスを作成する方法を示します。
自由にデザインをカスタマイズし、ユーザー レビューや映画の評価などの機能を追加して、よりダイナミックなものにしてください。
クレジット
- OMDB API
- 反応
- 反応ルーター
著者
Abhishek Gurjar は、実用的で機能的な Web アプリケーションの作成に情熱を注ぐ専任の Web 開発者です。 GitHub で彼のプロジェクトをさらにチェックしてください。
以上がReact を使用して Movie Finder Web サイトを構築するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

最近、製品画像の色を動的に更新するソリューションを見つけました。したがって、製品の1つだけで、私たちはそれをさまざまな方法で色付けすることができます

今週のラウンドアップでは、灯台はサードパーティのスクリプトに光を当て、安全なリソースが安全なサイトでブロックされ、多くの国の接続速度がブロックされます

サイトの訪問者と使用データを追跡するのに役立つ分析プラットフォームがたくさんあります。おそらく、特にGoogleアナリティクスが広く使用されています

ドキュメントヘッドはウェブサイトの中で最も魅力的な部分ではないかもしれませんが、それに入るものは間違いなくあなたのウェブサイトの成功にとってそれと同じくらい重要です

子のクラスでsuper()?を呼び出すJavaScriptを見たときに何が起こっているのか、Super()を使用して親のコンストラクターとSuperを呼び出します。そのアクセス

JavaScriptには、ユーザーインタラクション用の特別なUIを表示するさまざまな内蔵ポップアップAPIがあります。有名:

先日、私は多くの企業がアクセス可能なウェブサイトを作るのに苦労している理由について、フロントエンドの人々とおしゃべりをしていました。アクセス可能なWebサイトがとても難しいのはなぜですか


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

WebStorm Mac版
便利なJavaScript開発ツール

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

Dreamweaver Mac版
ビジュアル Web 開発ツール
