Build a movie search app in React
We are building a basic Movie search by using React and movie database API
Prerequisite
- Html
- Css
- Basic Javascript
- React , React function components ,React Hooks
How to get your API key ๐
We are using the movie database API for fetching the information. You can get your free unique API key by following steps in this guide API key
Let's Start Building ๐
Let's create a react web app first ( If you don't know how to create react app refer to this guide create-react-app )
import React from 'react';
import ReactDOM from 'react-dom';
class Main extends React.Component {
render() {
return (
<div className="container">
<h1 className="title">React Movie Search</h1>
</div>
);
}
}
ReactDOM.render(<Main />, document.getElementById('root'));
we will create a search movies component and create a form in which we will take an input tag to take the input of the user. We will call this component from our main app.js component.
import React from "react";
export default function SearchMovies(){
return (
<form className="form">
<label className="label" htmlFor="query">Movie Name</label>
<input className="input" type="text" name="query"
placeholder="i.e. Steve Jobs"/>
<button className="button" type="submit">Search</button>
</form>
)
}
Creating Search Movies Function
We are creating an onSubmit handler in form.
Copy-paste your API key in Place of 2cd6a26170cb9b78eb04ee871640f64z in const URL, const URL is the URL through which we talk to movie database API
${query} is where we are going to pass the movie name.
We will use fetch to get the data and convert it into JSON format and add it into the try-catch block to check if there is an error. you can go and see in the console what data we are getting.
NOTE: Do change 2cd6a26170cb9b78eb04ee871640f64z with your API key or it will not work.
import React from "react";
const searchMovies = async (e) => {
e.preventDefault();
const query = "Steve Jobs";
const url = `https://api.themoviedb.org/3/search/movie?api_key=2cd6a26170cb9b78eb04ee871640f64z&language=en-US&query=${query}&page=1&include_adult=false`;
try {
const res = await fetch(url);
const data = await res.json();
console.log(data);
}catch(err){
console.error(err);
}
}
return (
<form className="form" onSubmit={searchMovies}>
<label className="label" htmlFor="query">Movie Name</label>
<input className="input" type="text" name="query"
placeholder="i.e. Steve Jobs"/>
<button className="button" type="submit">Search</button>
</form>
)
}
Displaying the fetched Data
We are using useState here for query passing and getting movies data back. useState allows you to add state to your functional components.
we pass the value in the input element and onChange we set the query updated.
To display the movie we have used the map function to traverse and display but first, we are filtering only those which have posters by using the filter. We are also displaying movie titles, movie release dates, movie votes respectively.
import React, {useState} from "react";
export default function SearchMovies(){
const [query, setQuery] = useState('');
const [movies, setMovies] = useState([]);
const searchMovies = async (e) => {
e.preventDefault();
const url = `https://api.themoviedb.org/3/search/movie?api_key=2cd6a26170cb9b78eb04ee871640f64z&language=en-US&query=${query}&page=1&include_adult=false`;
try {
const res = await fetch(url);
const data = await res.json();
setMovies(data.results);
}catch(err){
console.error(err);
}
}
return (
<>
<form className="form" onSubmit={searchMovies}>
<label className="label" htmlFor="query">Movie Name</label>
<input className="input" type="text" name="query"
placeholder="i.e. Steve Jobs"
value={query} onChange={(e) => setQuery(e.target.value)}
/>
<button className="button" type="submit">Search</button>
</form>
<div className="card-list">
{movies.filter(movie => movie.poster_path).map(movie => (
<div className="card" key={movie.id}>
<img className="card--image"
src={`https://image.tmdb.org/t/p/w185_and_h278_bestv2/${movie.poster_path}`}
alt={movie.title + ' poster'}
/>
<div className="card--content">
<h3 className="card--title">{movie.title}</h3>
<p><small>RELEASE DATE: {movie.release_date}</small></p>
<p><small>RATING: {movie.vote_average}</small></p>
<p className="card--desc">{movie.overview}</p>
</div>
</div>
))}
</div>
</>
)
}
Styling your Movie App
style your app I have directly provided the style code you can change according to your needs.
html {
font-size: 10px;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
background-color: rgb(244,244,244);
color: #333;
}
p {
font-size: 1.6rem;
}
small {
font-size: 1.2rem;
}
.container {
margin: 0 auto;
max-width:1000px;
padding: 40px;
}
.title {
font-size: 4.4rem;
text-align: center
}
.form {
display:grid;
}
.label {
font-size: 1.2rem;
margin-bottom: 0.2rem;
text-transform: uppercase;
}
.input {
font-size: 1.6rem;
padding: 0.5rem 2rem;
line-height: 2.8rem;
border-radius: 20px;
border: 1px solid #ddd;
margin-bottom: 1rem;
}
.button {
background-color: rgba(0,0,0,0.75);
color: white;
padding: 1rem 2rem;
border: 1px solid rgba(0,0,0,0.75);
border-radius: 20px;
font-size: 1.4rem;
cursor: pointer;
transition: background-color 250ms;
}
.button:hover {
background-color: rgba(0,0,0,0.85);
}
@media (min-width:786px){
.form {
grid-template-columns: auto 1fr auto;
grid-gap: 1rem;
align-items: center;
}
.input {
margin-bottom: 0;
}
}
.card-list {
margin-top: 4rem;
}
.card {
padding: 2rem 4rem;
border-radius: 10px;
box-shadow: 1px 1px 5px rgba(0,0,0,0.25);
margin-bottom: 2rem;
background-color: white;
}
.card--title {
margin-bottom: 0.5rem;
font-size: 3.2rem;
}
.card--image {
margin: 0 auto;
display: block
}
Deploying
you can deploy it for free using netlify or Github and share it with your friends.
Hurray you did it ๐
If you are reading till here I hope you go out there and try to build it. If you don't understand any concept docs are the best place to learn about it.
Congratulate yourself if you made it.
Do tell me if there is any improvement I should make to the blog.
Try this out
you can hide the API key in env and access it directly, It is always better to hide your API key for safety reasons Try that out too.