
介绍
在本博客中,我们将逐步介绍使用 react 和 omdb api 构建 movie finder 网站的过程。该网站允许用户按复仇者联盟、星球大战和系列等类别浏览电影,并使用特定查询搜索电影。每部电影都有其详细页面,让您轻松探索更多有关您喜爱的电影。
项目概况
电影查找网站使用户能够:
浏览复仇者联盟和星球大战等类别。通过关键字搜索电影。查看详细的电影信息(海报、类型、导演、演员等)。通过简洁、现代的设计轻松浏览网站。
特征
使用 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.gitcd movie-finder
安装依赖项:
npm install
从 omdb api 获取您的 api 密钥。
在项目根目录中创建一个 .env 文件并添加您的 api 密钥:
react_app_omdb_api_key=yourapikey
运行项目:
npm start
用法
1. 主页
主页展示了两类电影:《复仇者联盟》和《星球大战》。当用户点击电影卡时,他们会被重定向到详细的电影页面。
来自 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 ? ( ) : ( {movies.length > 0 ? ( movies.map((movie) => ( handlecardclick(movie.imdbid)}> @@##@@ {movie.title}
)) ) : ( no movies found.
)} ) ); return ( avengers movies
{rendermovies(avengersmovies, loadingavengers)}
star wars movies
{rendermovies(starwarsmovies, loadingstarwars)} > );};export default home;</pre>2. 搜索功能
用户可以使用网站顶部的搜索栏搜索任何电影。搜索结果是根据用户的查询从 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 ( search results for "{query}"
{loading ? ( // loader ) : ( {movies.length > 0 ? ( movies.map((movie) => ( handlecardclick(movie.imdbid)}> @@##@@ {movie.title}
)) ) : ( no results found.
)} )} );};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 ; if (!movie) return no movie data found!; return ( {movie.title}
year: {movie.year}
rating: {movie.imdbrating}
DouPHP轻量级外贸商城系统 DouPHP模块化企业网站管理系统是一款轻量级企业网站管理系统,基于PHP+MYSQL架构的,包含“手机版”、“公众号管理模块”、“小程序”,可以使用它快速搭建一个企业网站。 DouPHP功能特色: (模块全部免费,一键安装) 功能性模块:防伪查询模块、投票模块、自定义表单模块、工单模块等、会员模块、订单模块、视频模块、下载模块、图片模块等; 企业官网模块:业务范围
0 查看详情
genre: {movie.genre}
director: {movie.director}
actors: {movie.actors}
plot: {movie.plot}
runtime: {movie.runtime}
language: {movie.language}
country: {movie.country}
awards: {movie.awards}
@@##@@ );};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 ( movies
{movies.map(movie => ( handlecardclick(movie.imdbid)}> @@##@@ {movie.title}
))} );};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 ( tv series
{series.map(show => ( handlecardclick(show.imdbid)}> @@##@@ {show.title}
))} );};export default series;
5. 导航栏组件
导航栏组件允许用户在不同页面之间导航并执行搜索。
更新了 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 ( movie finder
home
movies
tv series
setsearchquery(e.target.value)} onkeydown={handlesearch} /> );};export default navbar;
6.页脚组件
页脚组件提供简单的页脚消息。
页脚.js
import react from 'react';const footer = () => { return ( made with ❤️ by abhishek gurjar );};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: */.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 网站的现场演示。
结论
在本博客中,我们学习了如何使用 react、react router 和 axios 创建 movie finder 网站。该项目演示了如何与公共 api 交互、在 react 中管理状态以及创建简单而实用的电影浏览体验。
随意定制设计并添加更多功能,例如用户评论或电影评分,使其更加动态!
制作人员
omdb api反应反应路由器
作者
abhishek gurjar 是一位专注的 web 开发人员,热衷于创建实用且功能性的 web 应用程序。在 github 上查看他的更多项目。





以上就是使用 React 构建电影查找网站的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1629875.html
微信扫一扫
支付宝扫一扫