使用 ReactJS 的電影 Web 應用程式
如今,OTT 平臺越來越受歡迎,人們正在訂閱各種 OTT 平臺以觀看電影、電視劇或服務。也許,你也可以啟動任何 OTT 應用程式。
在本教程中,我們將學習如何使用 React JS 建立電影 Web 應用程式。但是,我們將學習編寫電影應用程式的基本程式碼。如果使用者需要,他們可以從以下程式碼開始並進行改進以建立電影 Web 應用程式的高階版本。
使用者應按照以下步驟開始使用電影 Web 應用程式。
步驟 1 - 在第一步中,我們需要建立 React 應用程式。使用者應在終端中執行以下命令以開始使用 React 電影應用程式。
npx create-react-app movie-app
步驟 2 - 透過執行以下命令在終端中移動到專案目錄。
cd movie-app
步驟 3 - 接下來,我們需要安裝所需的依賴項,方法是執行以下命令。
npm install react-router-dom axios
這裡,axios 用於獲取資料,react-router-dom 用於配置應用程式的路由。
步驟 4 - 接下來,我們需要在 App.js 檔案中設定應用程式的路由。
步驟 4.1 - 匯入所需的函式和元件。
步驟 4.2 - 為“/”主頁路由顯示 Home 元件。
步驟 4.3 - 為“movie/:id”路由顯示 movieDetails 元件。這裡,id 是一個變數。
步驟 4.4 - 在 App.js 檔案中新增以下程式碼。
檔名 – App.js
import { BrowserRouter, Routes, Route } from "react-router-dom"; import Home from "./components/home"; import MovieDetails from "./components/MovieDetails"; function App() { // creating routers using react-router-dom return ( <BrowserRouter> <Routes> {/* home route */} <Route path = "/" element = {<Home />} /> {/* movie route */} <Route path = "/movie/:id" element = {<MovieDetails />} /> </Routes> </BrowserRouter> ); } export default App;
步驟 5 - 接下來,在“src”目錄中建立一個 components 資料夾,並新增“Home.js”檔案。
步驟 5.1 - 匯入所需的元件和“axios”。
步驟 5.2 - 建立一個狀態來儲存我們從 API 獲取的所有電影。
步驟 5.3 - 定義 handleSearchInput() 函式,該函式處理搜尋輸入值。
步驟 5.3 - 定義 executeSearch() 函式。在函式中,檢查使用者是否按下了“Enter”鍵。如果是,則使用“axios”獲取資料並將其儲存在 results 變數中。同時,使用結果值更新狀態。
步驟 5.4 - 在網頁上呈現搜尋輸入。此外,透過將從 API 獲取的電影資料傳遞到 Web 應用程式,呈現 AllMovies 元件。
在 Home.js 檔案中新增以下程式碼。
檔名 – Home.js
import React, { useState } from "react"; import AllMovies from "./AllMovies"; import axios from "axios"; import "../App.css"; function Home() { // create a state to store fetched data const [initial, setStateValues] = useState({ searchValue: "sherlock", allMovies: [], }); // movie api url with api key const movieApiURL = "https://www.omdbapi.com/?apikey=a2526df0"; // function to handle search input function handleSearchInput(event) { // get search value let searchValue = event.target.value; // set search value to the state setStateValues((rest) => { return { ...rest, searchValue: searchValue }; }); } // function to execute a search async function executeSearch(event) { // check if enter key is pressed if (event.key === "Enter") { // fetch movies let movies = await axios(movieApiURL + "&s=" + initial.searchValue); // get results let results = movies.data.Search; // set results to state setStateValues((prevState) => { return { ...prevState, allMovies: results }; }); } } return ( <div className = "App"> <header className = "App-header"> <h2> Web application for Movies </h2> </header> <main> {/* show search bar */} <div className = "search-div"> <input type = "text" placeholder = "Search movie name..." className = "search-input" onChange = {handleSearchInput} onKeyPress = {executeSearch} /> </div> {/* show resultant movies */} <AllMovies movies = {initial.allMovies} /> </main> </div> ); } export default Home;
步驟 6 - 在“components”目錄中建立一個 AllMovies.js 檔案以卡片形式顯示電影。
步驟 6.1 - 在這裡,我們獲取電影資料作為道具。首先,我們需要檢查“movies”是否包含資料或未定義。如果未定義,則表示資料庫中未找到任何相關電影。因此,在網頁上相應地顯示訊息。
步驟 6.2 - 如果 movies 包含資料,則使用“map”方法遍歷陣列,併為每部電影建立一個卡片。在卡片上,我們顯示電影海報和標題。
步驟 6.3 - 在 AllMovies.js 檔案中新增以下程式碼。
檔名 – AllMovies.js
import React from "react"; import { Link } from "react-router-dom"; function AllMovies({ movies: movies }) { return ( <div className = "allMovies"> {/* show all movies using map method */} {typeof movies != "undefined" ? ( movies.map((result) => ( // render single movie <div className = "movie"> {/* set link for movie card */} <Link to = {`/movie/${result.imdbID}`}> {/* show movie poster and title */} <img src = {result.Poster} alt = "movie poster" /> <h3> {result.Title} </h3> </Link> </div> )) ) : ( <div className = "no-movie"> <h2> Oops! We haven't listed the movie yet, or it might not exist in the database. {" "} </h2> <h2> Kindly check the movie name once. </h2> </div> )} </div> ); } export default AllMovies;
步驟 7 - 現在,在“components”目錄中建立一個“MovieDetails.js”檔案以顯示單個電影詳細資訊。
步驟 7.1 - 使用“useParams”建構函式從 URL 獲取引數。
步驟 7.2 - 使用 axios 使用從 URL 引數獲取的電影 ID 獲取電影資料。
步驟 7.3 - 在網頁上呈現電影資訊,這些資訊是從 API 獲取的。
步驟 7.4 - 此外,新增關閉按鈕以返回。
在“MovieDetails.js”檔案中新增以下程式碼。
檔名 – MovieDetails.js
import React from "react"; import { useParams } from "react-router-dom"; import axios from "axios"; import { useState } from "react"; import { Link } from "react-router-dom"; function MovieDetails() { // Get ID from URL const params = useParams(); const movieApiURL = "https://www.omdbapi.com/?apikey=a2526df0"; let [movieDetails, setMovieDetails] = useState({}); // function to fetch data function fetchData() { // fetch movie details according to id axios(movieApiURL + "&i=" + params.id).then(({ data }) => { let result = data; setMovieDetails(result); }); } fetchData(); return ( // show movie details with image, title, year, rating, type and plot <div className = "movieDetail"> <div className = "description"> {/* show poster */} <img src = {movieDetails.Poster} alt = "Movie poster" /> <div className = "details"> <h2> {movieDetails.Title} </h2> <p> Year : {movieDetails.Year} </p> <p className = "rating"> Rating: {movieDetails.imdbRating} </p> <p> Type: {movieDetails.Type} </p> <p> {movieDetails.Plot} </p> <button className = "back"> {/* link to home page */} <Link to = {`/`}> Go back </Link> </button> </div> </div> </div> ); } export default MovieDetails;
步驟 8 - 現在,將 CSS 新增到 App.css 檔案。在這裡,我們對搜尋欄、電影卡片和 MovieDetails 元件進行了樣式設定,以便正確顯示詳細資訊。
檔名 – App.css
* { box-sizing: border-box; margin: 0; padding: 0; } body { background: linear-gradient(to left, green, blue, red); } header { width: 90%; padding-top: 25px; padding-bottom: 15px; margin: 0 auto; } header h2 { color: white; font-size: 50px; font-weight: 600; text-align: center; } main { width: 100%; max-width: 90%; margin: 0 auto; } .allMovies { display: flex; flex-wrap: wrap; width: 95%; justify-content: center; align-items: center; text-decoration: none; } .allMovies .movie { width: clamp(300px, 20%, 500px); background: rgb(167, 0, 245); max-height: 500px; border-radius: 12px; padding: 10px; margin: 20px 25px; display: flex; flex-direction: column; cursor: pointer; } .allMovies .no-movie { display: flex; flex-direction: column; justify-content: center; margin: 2rem 0.5rem; align-items: center; text-align: center; color: white; } .allMovies .movie img { width: 100%; border-radius: 12px; padding: 10px 2px; margin: 0 auto; height: 350px; } .allMovies .movie h3 { text-decoration: none; color: white; font-size: 20px; font-weight: 600; border-radius: 12px; width: 100%; text-align: center; padding: 1rem; background: green; transition: 0.4s ease-out; } .movie:hover { box-shadow: 0 0 10px 4px yellow; } .allMovies .movie h3:hover { background: aqua; color: blue; box-shadow: 0 0 8px 3px #4484c4; } .movieDetail { margin: 3rem 5rem; overflow-y: auto; width: 90%; } .movieDetail .description .rating { margin: 10px 40px; font-size: 1.5rem; padding-bottom: 0; } .movieDetail .description { position: fixed; display: flex; top: 0; left: 0; width: 100%; height: 100%; padding: 25px; background: blue; color: white; overflow-y: auto; } .movieDetail .description .details h2 { padding: 2rem; margin-top: 1rem; font-size: 45px; padding-bottom: 0.5rem; font-weight: 600; } .movieDetail .description .details p { font-size: 1.4rem; color: white; margin-left: 40px; } .movieDetail .description img { max-width: 45%; padding: 0 15px; margin-left: 2rem; margin-right: 2rem; margin-top: 1rem; } .movieDetail .description .details .back { padding: 15px 30px; font-size: 28px; font-weight: 700; background: red; display: flex; margin: auto; margin-top: 5rem; color: white; border: none; outline: none; appearance: none; justify-content: center; align-items: center; border-radius: 5px; cursor: pointer; transition: 0.4s ease-out; width: 90%; } .movieDetail .description .details button:hover { background: #4484c4; } @media screen and (max-width: 1020px) { .allMovies { justify-content: center; align-items: center; } .movieDetail .description .back { width: 100%; display: flex; justify-content: center; align-items: center; border-radius: 5px; margin: auto; } } @media screen and (max-width: 720px) { .allMovies { justify-content: center; align-items: center; } .allMovies .movie { margin: 10px; justify-content: center; align-items: center; } } @media screen and (max-width: 480px) { header h1 { font-size: 2.9rem; } .allMovies { display: flex; flex-direction: column; justify-content: center; align-items: center; } .movieDetail { flex-direction: column; overflow-y: scroll; } } /* CSS for search */ .search-div { display: flex; justify-content: center; align-items: center; margin: 1rem 0; } .search-input { width: 70%; display: block; padding: 15px; border: none; font-size: 20px; font-weight: 300; outline: none; background: none; background-color: aqua; border-radius: 12px; color: blue; transition: 0.4s ease-out; } .search-input:focus { box-shadow: 0 0 8px 3px #4484c4; } @media screen and (max-width: 720px) { .search-input { width: 80%; } } @media screen and (max-width: 480px) { .search-input { width: 95%; } }
步驟 9 - 我們已成功建立了電影 Web 應用程式。現在,是時候測試專案了。在終端中使用以下命令執行專案。
npm run start
步驟 10 - 開啟 localhost:3000 以檢視以下介面。在搜尋欄中,至少搜尋電影名稱的前三個字元,您將在下方看到結果。

步驟 11 - 如果您點選任何電影卡片,它將向您顯示所有與電影相關的詳細資訊,如下所示。
我們已成功使用 ReactJS 建立了電影 Web 應用程式。開發人員可以新增諸如“新增到收藏夾”之類的額外功能來增強應用程式。開發人員應嘗試使用本地儲存來實現“新增到收藏夾”功能。因此,當用戶點選“新增到收藏夾”按鈕時,我們可以將該電影資料儲存在本地儲存中。