使用React和API的电影搜索引擎

使用React和API的电影搜索引擎

在本文中,我们将使用ReactJS创建电影搜索引擎。在这个电影搜索引擎中,用户可以搜索他们想要了解的电影,并且搜索引擎将根据关键字获取电影列表,并以卡片形式显示结果。初始加载了一个默认搜索来显示电影。

该项目主要实现了类的功能组件,并相应地管理状态。应用程序用户使用搜索栏搜索电影,然后应用程序返回有关搜索电影的信息。搜索电影和获取搜索电影结果的逻辑是使用JSX实现的。

让我们交互地看一下我们最终项目的样子:

使用React和API的电影搜索引擎

使用的技术 / 先决条件:

  • ReactJS
  • CSS
  • JSX
  • React中的功能组件

方法

使用ReactJS创建电影搜索引擎时,我们设置项目,为用户输入创建SearchBar组件,使用useState钩子来管理搜索词的状态,使用useEffect钩子从API获取电影数据,使用JSX在MovieList组件中渲染电影信息,将组件组合在主App组件中,使用CSS为组件添加样式,并通过运行应用程序并在搜索栏中输入电影标题来测试应用程序。

项目结构:

使用React和API的电影搜索引擎

创建应用程序的步骤:

步骤1:VSCode IDE中使用以下命令设置React项目。

npx create-react-app <<name of project>>  

步骤2: 通过执行以下命令导航到新创建的项目文件夹。

cd <<Name_of_project>>  

步骤3: 创建一个名为MovieCard.jsx的文件。我们将使用现有的App.js和App.css文件来执行应用程序的行为和样式。

将下面提到的代码写入不同的文件中(每个代码块的第一行中提到了文件的名称)。

示例:

  • index.html 这是在public文件夹中自动生成的文件,我们只需在其标签中导入图标包即可。
  • App.js: 该文件导入了电影组件并将其导出。
  • MovieCard.jsx: 此文件以卡片或网格形式显示电影的表示形式。使用此文件将调用API来获取搜索到的电影。
  • App.css 此文件包含电影搜索引擎元素的设计。
// App.js 
  
import React, { useState } from 'react'; 
import { useEffect } from 'react'; 
import './App.css'; 
import MovieCard from './MovieCard'; 
  
const API_URL = 'https://omdbapi.com?apikey=fe2f6c44'; 
const App = () => { 
    const [movies, setMovies] = useState([]); 
    const [searchTerm, setSearchTerm] = useState([]); 
    const searchMovies = async (title) => { 
        const response = await fetch(`{API_URL}&s={title}`); 
        const data = await response.json(); 
        setMovies(data.Search); 
    } 
    useEffect(() => { 
        searchMovies('SpiderMan'); 
    }, []); 
    return ( 
        <div className="app"> 
            <h1>GeeksforGeeks's Movie Center</h1> 
  
            <div className="search"> 
                <input 
                    placeholder="Search for Movies"
                    value={searchTerm} 
                    onChange={(e) => { setSearchTerm(e.target.value) }} 
                /> 
                <img 
                    src= 
"https://media.geeksforgeeks.org/wp-content/uploads/20230626112934/search.png"
                    alt="search icon"
                    onClick={() => searchMovies(searchTerm)} 
                /> 
            </div> 
  
            { 
                movies?.length > 0 
                    ? (<div className="container"> 
                        {movies.map((movie) => ( 
                            <MovieCard movie={movie} /> 
                        ))} 
                    </div>) : ( 
                        <div className="empty"> 
                            <h2>No Movies found</h2> 
                        </div> 
                    ) 
            } 
        </div> 
    ); 
} 
export default App;

MovieCard.jsx

// MovieCard.jsx 
import React from 'react'; 
// import App from './App'; 
const MovieCard = ({ movie }) => { 
    return ( 
        <div className="movie"> 
            <div> 
                <p>{movie.Title}</p> 
            </div> 
            <div> 
                <img src={movie.Poster !== 'N/A' ? movie.Poster : "https://via.placeholder.com/400"} alt={movie.Title} /> 
            </div> 
            <div> 
                <span>{movie.Type}</span> 
                <h3>{movie.Title}</h3> 
            </div> 
        </div> 
    ) 
} 
export default MovieCard;

HTML

<!--index.html-->
<!DOCTYPE html> 
<html lang="en"> 
  
<head> 
    <meta charset="utf-8" /> 
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> 
    <meta name="viewport" content="width=device-width, initial-scale=1" /> 
    <meta name="theme-color" content="#000000" /> 
    <meta name="description" content="Web site created using create-react-app" /> 
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> 
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> 
    <title>GeeksforGeeks Movie's Center</title> 
</head> 
  
<body> 
    <noscript>You need to enable JavaScript to run this app.</noscript> 
    <div id="root"></div> 
</body> 
  
</html>

CSS

/* App.css */
@import url("https://fonts.googleapis.com/css?family=Roboto+Slab:100,300,400,700"); 
@import url("https://fonts.googleapis.com/css?family=Raleway:300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i"); 
  
* { 
    margin: 0; 
    border: 0; 
    box-sizing: border-box; 
} 
  
:root { 
    --font-roboto: "Roboto Slab", serif; 
    --font-raleway: "Raleway", sans-serif; 
} 
  
body { 
    font-family: var(--font-roboto); 
    background-color: #212426; 
} 
  
.app { 
    padding: 4rem; 
    display: flex; 
    justify-content: center; 
    align-items: center; 
    flex-direction: column; 
} 
  
h1 { 
    font-size: 3rem; 
    letter-spacing: 0.9px; 
    background: linear-gradient(90deg, 
            rgba(249, 211, 180, 1) 0%, 
            rgba(249, 211, 180, 0) 100%); 
    background-clip: text; 
    -webkit-background-clip: text; 
    -webkit-text-fill-color: transparent; 
    width: fit-content; 
} 
  
.search { 
    width: 71%; 
    margin: 4rem 0 2rem; 
  
    display: flex; 
    align-items: center; 
    justify-content: center; 
  
    padding: 1.5rem 1.75rem; 
    border-radius: 3rem; 
    background: #1f2123; 
    -webkit-box-shadow: 5px 5px 7px #1c1d1f, -5px -5px 7px #222527; 
    box-shadow: 5px 5px 7px #1c1d1f, -5px -5px 7px #222527; 
} 
  
.search input { 
    flex: 1; 
    border: none; 
    font-size: 1.5rem; 
    font-family: var(--font-raleway); 
    font-weight: 500; 
    padding-right: 1rem; 
  
    outline: none; 
    color: #a1a1a1; 
    background: #1f2123; 
} 
  
.search img { 
    width: 35px; 
    height: 35px; 
    cursor: pointer; 
} 
  
.empty { 
    width: 100%; 
    margin-top: 3rem; 
  
    display: flex; 
    justify-content: center; 
    align-items: center; 
} 
  
.empty h2 { 
    font-size: 1.25rem; 
    color: #f9d3b4; 
    font-family: var(--font-raleway); 
} 
  
.container { 
    width: 100%; 
    margin-top: 3rem; 
  
    display: flex; 
    justify-content: center; 
    align-items: center; 
    flex-wrap: wrap; 
} 
  
.movie { 
    width: 310px; 
    height: 460px; 
    margin: 1.5rem; 
  
    position: relative; 
    border-radius: 12px; 
    overflow: hidden; 
    border: none; 
  
    transition: all 0.4s cubic-bezier(0.175, 0.885, 0, 1); 
    box-shadow: 0px 13px 10px -7px rgba(0, 0, 0, 0.1); 
} 
  
.movie div:nth-of-type(1) { 
    position: absolute; 
    padding: 16px; 
    width: 100%; 
    opacity: 0; 
    top: 0; 
    color: #f9d3b4; 
} 
  
.movie:hover { 
    box-shadow: 0px 30px 18px -8px rgba(0, 0, 0, 0.1); 
    transform: scale(1.05, 1.05); 
} 
  
.movie div:nth-of-type(2) { 
    width: 100%; 
    height: 100%; 
} 
  
.movie div:nth-of-type(2) img { 
    height: 100%; 
    width: 100%; 
} 
  
.movie div:nth-of-type(3) { 
    z-index: 2; 
    background-color: #343739; 
    padding: 16px 24px 24px 24px; 
  
    position: absolute; 
    bottom: 0; 
    right: 0; 
    left: 0; 
} 
  
.movie div:nth-of-type(3) span { 
    font-family: "Raleway", sans-serif; 
    text-transform: uppercase; 
    font-size: 13px; 
    letter-spacing: 2px; 
    font-weight: 500; 
    color: #f0f0f0; 
} 
  
.movie div:nth-of-type(3) h3 { 
    margin-top: 5px; 
    font-family: "Roboto Slab", serif; 
    color: #f9d3b4; 
} 
  
.movie:hover div:nth-of-type(2) { 
    height: 100%; 
    opacity: 0.3; 
} 
  
.movie:hover div:nth-of-type(3) { 
    background-color: transparent; 
} 
  
.movie:hover div:nth-of-type(1) { 
    opacity: 1; 
} 
  
@media screen and (max-width: 600px) { 
    .app { 
        padding: 4rem 2rem; 
    } 
  
    .search { 
        padding: 1rem 1.75rem; 
        width: 100%; 
    } 
  
    .search input { 
        font-size: 1rem; 
    } 
  
    .search img { 
        width: 20px; 
        height: 20px; 
    } 
} 
  
@media screen and (max-width: 400px) { 
    .app { 
        padding: 4rem 1rem; 
    } 
  
    h1 { 
        font-size: 2rem; 
    } 
  
    .container { 
        margin-top: 2rem; 
    } 
  
    .movie { 
        width: "100%"; 
        margin: 1rem; 
    } 
}

运行应用的步骤:

1. 在终端中执行以下命令。

npm start  

2. 打开网页浏览器,并在地址栏中输入以下URL。

http://localhost:3000/  

输出:

使用React和API的电影搜索引擎

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程