使用 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 應用程式。開發人員可以新增諸如“新增到收藏夾”之類的額外功能來增強應用程式。開發人員應嘗試使用本地儲存來實現“新增到收藏夾”功能。因此,當用戶點選“新增到收藏夾”按鈕時,我們可以將該電影資料儲存在本地儲存中。

更新於:2023 年 5 月 5 日

702 次檢視

啟動您的 職業生涯

透過完成課程獲得認證

開始
廣告